2017-12-19 15:49:02 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright(c) 2010-2016 Intel Corporation
|
2012-09-04 12:54:00 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <inttypes.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <sys/queue.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <getopt.h>
|
2015-12-30 21:59:51 +00:00
|
|
|
#include <signal.h>
|
|
|
|
#include <stdbool.h>
|
2012-09-04 12:54:00 +00:00
|
|
|
|
|
|
|
#include <rte_common.h>
|
2015-03-18 17:08:15 +00:00
|
|
|
#include <rte_vect.h>
|
2012-09-04 12:54:00 +00:00
|
|
|
#include <rte_byteorder.h>
|
|
|
|
#include <rte_log.h>
|
|
|
|
#include <rte_memory.h>
|
|
|
|
#include <rte_memcpy.h>
|
|
|
|
#include <rte_eal.h>
|
|
|
|
#include <rte_launch.h>
|
|
|
|
#include <rte_atomic.h>
|
|
|
|
#include <rte_cycles.h>
|
|
|
|
#include <rte_prefetch.h>
|
|
|
|
#include <rte_lcore.h>
|
|
|
|
#include <rte_per_lcore.h>
|
|
|
|
#include <rte_branch_prediction.h>
|
|
|
|
#include <rte_interrupts.h>
|
|
|
|
#include <rte_random.h>
|
|
|
|
#include <rte_debug.h>
|
|
|
|
#include <rte_ether.h>
|
|
|
|
#include <rte_ethdev.h>
|
|
|
|
#include <rte_mempool.h>
|
|
|
|
#include <rte_mbuf.h>
|
|
|
|
#include <rte_ip.h>
|
|
|
|
#include <rte_tcp.h>
|
|
|
|
#include <rte_udp.h>
|
|
|
|
#include <rte_string_fns.h>
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
#include <rte_cpuflags.h>
|
2012-09-04 12:54:00 +00:00
|
|
|
|
2015-05-18 12:13:24 +00:00
|
|
|
#include <cmdline_parse.h>
|
|
|
|
#include <cmdline_parse_etheraddr.h>
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
#include "l3fwd.h"
|
2012-12-19 23:00:00 +00:00
|
|
|
|
|
|
|
/*
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
* Configurable number of RX/TX ring descriptors
|
2012-12-19 23:00:00 +00:00
|
|
|
*/
|
2018-01-12 10:48:44 +00:00
|
|
|
#define RTE_TEST_RX_DESC_DEFAULT 1024
|
|
|
|
#define RTE_TEST_TX_DESC_DEFAULT 1024
|
2012-12-19 23:00:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
#define MAX_TX_QUEUE_PER_PORT RTE_MAX_ETHPORTS
|
|
|
|
#define MAX_RX_QUEUE_PER_PORT 128
|
2012-09-04 12:54:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
#define MAX_LCORE_PARAMS 1024
|
2012-09-04 12:54:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/* Static global variables used within this file. */
|
|
|
|
static uint16_t nb_rxd = RTE_TEST_RX_DESC_DEFAULT;
|
|
|
|
static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/**< Ports set in promiscuous mode off by default. */
|
|
|
|
static int promiscuous_on;
|
2012-09-04 12:54:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/* Select Longest-Prefix or Exact match. */
|
|
|
|
static int l3fwd_lpm_on;
|
|
|
|
static int l3fwd_em_on;
|
2012-09-04 12:54:00 +00:00
|
|
|
|
2019-04-25 09:40:19 +00:00
|
|
|
/* Global variables. */
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
static int numa_on = 1; /**< NUMA is enabled by default. */
|
2016-03-25 00:47:46 +00:00
|
|
|
static int parse_ptype; /**< Parse packet type using rx callback, and */
|
|
|
|
/**< disabled by default */
|
2019-04-25 09:40:19 +00:00
|
|
|
static int per_port_pool; /**< Use separate buffer pools per port; disabled */
|
|
|
|
/**< by default */
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
volatile bool force_quit;
|
2012-09-04 12:54:00 +00:00
|
|
|
|
|
|
|
/* ethernet addresses of ports */
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
uint64_t dest_eth_addr[RTE_MAX_ETHPORTS];
|
2019-05-21 16:13:03 +00:00
|
|
|
struct rte_ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
|
2016-03-10 16:06:22 +00:00
|
|
|
xmm_t val_eth[RTE_MAX_ETHPORTS];
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
/* mask of enabled ports */
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
uint32_t enabled_port_mask;
|
2013-06-03 00:00:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/* Used only in exact match mode. */
|
|
|
|
int ipv6; /**< ipv6 is false by default. */
|
|
|
|
uint32_t hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT;
|
2012-09-04 12:54:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
struct lcore_conf lcore_conf[RTE_MAX_LCORE];
|
2012-09-04 12:54:00 +00:00
|
|
|
|
|
|
|
struct lcore_params {
|
2017-09-29 07:17:24 +00:00
|
|
|
uint16_t port_id;
|
2012-09-04 12:54:00 +00:00
|
|
|
uint8_t queue_id;
|
|
|
|
uint8_t lcore_id;
|
|
|
|
} __rte_cache_aligned;
|
|
|
|
|
|
|
|
static struct lcore_params lcore_params_array[MAX_LCORE_PARAMS];
|
|
|
|
static struct lcore_params lcore_params_array_default[] = {
|
|
|
|
{0, 0, 2},
|
|
|
|
{0, 1, 2},
|
|
|
|
{0, 2, 2},
|
|
|
|
{1, 0, 2},
|
|
|
|
{1, 1, 2},
|
|
|
|
{1, 2, 2},
|
|
|
|
{2, 0, 2},
|
|
|
|
{3, 0, 3},
|
|
|
|
{3, 1, 3},
|
|
|
|
};
|
|
|
|
|
|
|
|
static struct lcore_params * lcore_params = lcore_params_array_default;
|
|
|
|
static uint16_t nb_lcore_params = sizeof(lcore_params_array_default) /
|
|
|
|
sizeof(lcore_params_array_default[0]);
|
|
|
|
|
|
|
|
static struct rte_eth_conf port_conf = {
|
|
|
|
.rxmode = {
|
2014-02-11 15:35:19 +00:00
|
|
|
.mq_mode = ETH_MQ_RX_RSS,
|
2019-05-21 16:13:05 +00:00
|
|
|
.max_rx_pkt_len = RTE_ETHER_MAX_LEN,
|
2012-09-04 12:54:00 +00:00
|
|
|
.split_hdr_size = 0,
|
2018-09-04 10:12:56 +00:00
|
|
|
.offloads = DEV_RX_OFFLOAD_CHECKSUM,
|
2012-09-04 12:54:00 +00:00
|
|
|
},
|
|
|
|
.rx_adv_conf = {
|
|
|
|
.rss_conf = {
|
|
|
|
.rss_key = NULL,
|
2014-06-05 05:08:50 +00:00
|
|
|
.rss_hf = ETH_RSS_IP,
|
2012-09-04 12:54:00 +00:00
|
|
|
},
|
|
|
|
},
|
|
|
|
.txmode = {
|
2013-06-03 00:00:00 +00:00
|
|
|
.mq_mode = ETH_MQ_TX_NONE,
|
2012-09-04 12:54:00 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2019-04-25 09:40:19 +00:00
|
|
|
static struct rte_mempool *pktmbuf_pool[RTE_MAX_ETHPORTS][NB_SOCKETS];
|
|
|
|
static uint8_t lkp_per_socket[NB_SOCKETS];
|
2012-09-04 12:54:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
struct l3fwd_lkp_mode {
|
|
|
|
void (*setup)(int);
|
2016-03-25 00:47:46 +00:00
|
|
|
int (*check_ptype)(int);
|
|
|
|
rte_rx_callback_fn cb_parse_ptype;
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
int (*main_loop)(void *);
|
|
|
|
void* (*get_ipv4_lookup_struct)(int);
|
|
|
|
void* (*get_ipv6_lookup_struct)(int);
|
2012-09-04 12:54:00 +00:00
|
|
|
};
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
static struct l3fwd_lkp_mode l3fwd_lkp;
|
2013-06-03 00:00:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
static struct l3fwd_lkp_mode l3fwd_em_lkp = {
|
|
|
|
.setup = setup_hash,
|
2016-03-25 00:47:46 +00:00
|
|
|
.check_ptype = em_check_ptype,
|
|
|
|
.cb_parse_ptype = em_cb_parse_ptype,
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
.main_loop = em_main_loop,
|
|
|
|
.get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
|
|
|
|
.get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
|
2012-09-04 12:54:00 +00:00
|
|
|
};
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
|
|
|
|
.setup = setup_lpm,
|
2016-03-25 00:47:46 +00:00
|
|
|
.check_ptype = lpm_check_ptype,
|
|
|
|
.cb_parse_ptype = lpm_cb_parse_ptype,
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
.main_loop = lpm_main_loop,
|
|
|
|
.get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
|
|
|
|
.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
|
2013-06-03 00:00:00 +00:00
|
|
|
};
|
|
|
|
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
/*
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
* Setup lookup methods for forwarding.
|
|
|
|
* Currently exact-match and longest-prefix-match
|
|
|
|
* are supported ones.
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
*/
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
static void
|
|
|
|
setup_l3fwd_lookup_tables(void)
|
2014-07-22 16:04:47 +00:00
|
|
|
{
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/* Setup HASH lookup functions. */
|
|
|
|
if (l3fwd_em_on)
|
|
|
|
l3fwd_lkp = l3fwd_em_lkp;
|
|
|
|
/* Setup LPM lookup functions. */
|
|
|
|
else
|
|
|
|
l3fwd_lkp = l3fwd_lpm_lkp;
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
check_lcore_params(void)
|
|
|
|
{
|
|
|
|
uint8_t queue, lcore;
|
|
|
|
uint16_t i;
|
|
|
|
int socketid;
|
|
|
|
|
|
|
|
for (i = 0; i < nb_lcore_params; ++i) {
|
|
|
|
queue = lcore_params[i].queue_id;
|
|
|
|
if (queue >= MAX_RX_QUEUE_PER_PORT) {
|
|
|
|
printf("invalid queue number: %hhu\n", queue);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
lcore = lcore_params[i].lcore_id;
|
|
|
|
if (!rte_lcore_is_enabled(lcore)) {
|
|
|
|
printf("error: lcore %hhu is not enabled in lcore mask\n", lcore);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((socketid = rte_lcore_to_socket_id(lcore) != 0) &&
|
|
|
|
(numa_on == 0)) {
|
|
|
|
printf("warning: lcore %hhu is on socket %d with numa off \n",
|
|
|
|
lcore, socketid);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2018-04-05 15:33:21 +00:00
|
|
|
check_port_config(void)
|
2012-09-04 12:54:00 +00:00
|
|
|
{
|
2017-09-29 07:17:24 +00:00
|
|
|
uint16_t portid;
|
2012-09-04 12:54:00 +00:00
|
|
|
uint16_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < nb_lcore_params; ++i) {
|
|
|
|
portid = lcore_params[i].port_id;
|
|
|
|
if ((enabled_port_mask & (1 << portid)) == 0) {
|
|
|
|
printf("port %u is not enabled in port mask\n", portid);
|
|
|
|
return -1;
|
|
|
|
}
|
2018-04-05 15:33:21 +00:00
|
|
|
if (!rte_eth_dev_is_valid_port(portid)) {
|
2012-09-04 12:54:00 +00:00
|
|
|
printf("port %u is not present on the board\n", portid);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint8_t
|
2017-09-29 07:17:24 +00:00
|
|
|
get_port_n_rx_queues(const uint16_t port)
|
2012-09-04 12:54:00 +00:00
|
|
|
{
|
|
|
|
int queue = -1;
|
|
|
|
uint16_t i;
|
|
|
|
|
|
|
|
for (i = 0; i < nb_lcore_params; ++i) {
|
2016-03-25 15:13:44 +00:00
|
|
|
if (lcore_params[i].port_id == port) {
|
|
|
|
if (lcore_params[i].queue_id == queue+1)
|
|
|
|
queue = lcore_params[i].queue_id;
|
|
|
|
else
|
|
|
|
rte_exit(EXIT_FAILURE, "queue ids of the port %d must be"
|
|
|
|
" in sequence and must start with 0\n",
|
|
|
|
lcore_params[i].port_id);
|
|
|
|
}
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
return (uint8_t)(++queue);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
init_lcore_rx_queues(void)
|
|
|
|
{
|
|
|
|
uint16_t i, nb_rx_queue;
|
|
|
|
uint8_t lcore;
|
|
|
|
|
|
|
|
for (i = 0; i < nb_lcore_params; ++i) {
|
|
|
|
lcore = lcore_params[i].lcore_id;
|
|
|
|
nb_rx_queue = lcore_conf[lcore].n_rx_queue;
|
|
|
|
if (nb_rx_queue >= MAX_RX_QUEUE_PER_LCORE) {
|
|
|
|
printf("error: too many queues (%u) for lcore: %u\n",
|
|
|
|
(unsigned)nb_rx_queue + 1, (unsigned)lcore);
|
|
|
|
return -1;
|
|
|
|
} else {
|
|
|
|
lcore_conf[lcore].rx_queue_list[nb_rx_queue].port_id =
|
|
|
|
lcore_params[i].port_id;
|
|
|
|
lcore_conf[lcore].rx_queue_list[nb_rx_queue].queue_id =
|
|
|
|
lcore_params[i].queue_id;
|
|
|
|
lcore_conf[lcore].n_rx_queue++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* display usage */
|
|
|
|
static void
|
|
|
|
print_usage(const char *prgname)
|
|
|
|
{
|
2017-12-11 23:12:58 +00:00
|
|
|
fprintf(stderr, "%s [EAL options] --"
|
2016-06-27 14:26:48 +00:00
|
|
|
" -p PORTMASK"
|
|
|
|
" [-P]"
|
|
|
|
" [-E]"
|
|
|
|
" [-L]"
|
|
|
|
" --config (port,queue,lcore)[,(port,queue,lcore)]"
|
|
|
|
" [--eth-dest=X,MM:MM:MM:MM:MM:MM]"
|
|
|
|
" [--enable-jumbo [--max-pkt-len PKTLEN]]"
|
|
|
|
" [--no-numa]"
|
|
|
|
" [--hash-entry-num]"
|
|
|
|
" [--ipv6]"
|
2019-04-25 09:40:19 +00:00
|
|
|
" [--parse-ptype]"
|
|
|
|
" [--per-port-pool]\n\n"
|
2016-06-27 14:26:48 +00:00
|
|
|
|
|
|
|
" -p PORTMASK: Hexadecimal bitmask of ports to configure\n"
|
|
|
|
" -P : Enable promiscuous mode\n"
|
|
|
|
" -E : Enable exact match\n"
|
|
|
|
" -L : Enable longest prefix match (default)\n"
|
|
|
|
" --config (port,queue,lcore): Rx queue configuration\n"
|
|
|
|
" --eth-dest=X,MM:MM:MM:MM:MM:MM: Ethernet destination for port X\n"
|
|
|
|
" --enable-jumbo: Enable jumbo frames\n"
|
|
|
|
" --max-pkt-len: Under the premise of enabling jumbo,\n"
|
|
|
|
" maximum packet length in decimal (64-9600)\n"
|
|
|
|
" --no-numa: Disable numa awareness\n"
|
|
|
|
" --hash-entry-num: Specify the hash entry number in hexadecimal to be setup\n"
|
|
|
|
" --ipv6: Set if running ipv6 packets\n"
|
2019-04-25 09:40:19 +00:00
|
|
|
" --parse-ptype: Set to use software to analyze packet type\n"
|
|
|
|
" --per-port-pool: Use separate buffer pool per port\n\n",
|
2012-09-04 12:54:00 +00:00
|
|
|
prgname);
|
|
|
|
}
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
static int
|
|
|
|
parse_max_pkt_len(const char *pktlen)
|
2012-12-19 23:00:00 +00:00
|
|
|
{
|
|
|
|
char *end = NULL;
|
|
|
|
unsigned long len;
|
|
|
|
|
|
|
|
/* parse decimal string */
|
|
|
|
len = strtoul(pktlen, &end, 10);
|
|
|
|
if ((pktlen[0] == '\0') || (end == NULL) || (*end != '\0'))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (len == 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return len;
|
|
|
|
}
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
static int
|
|
|
|
parse_portmask(const char *portmask)
|
|
|
|
{
|
|
|
|
char *end = NULL;
|
|
|
|
unsigned long pm;
|
|
|
|
|
|
|
|
/* parse hexadecimal string */
|
|
|
|
pm = strtoul(portmask, &end, 16);
|
|
|
|
if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (pm == 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return pm;
|
|
|
|
}
|
|
|
|
|
2013-06-03 00:00:00 +00:00
|
|
|
static int
|
|
|
|
parse_hash_entry_number(const char *hash_entry_num)
|
|
|
|
{
|
|
|
|
char *end = NULL;
|
|
|
|
unsigned long hash_en;
|
|
|
|
/* parse hexadecimal string */
|
|
|
|
hash_en = strtoul(hash_entry_num, &end, 16);
|
|
|
|
if ((hash_entry_num[0] == '\0') || (end == NULL) || (*end != '\0'))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
if (hash_en == 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return hash_en;
|
|
|
|
}
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
static int
|
|
|
|
parse_config(const char *q_arg)
|
|
|
|
{
|
|
|
|
char s[256];
|
|
|
|
const char *p, *p0 = q_arg;
|
|
|
|
char *end;
|
|
|
|
enum fieldnames {
|
|
|
|
FLD_PORT = 0,
|
|
|
|
FLD_QUEUE,
|
|
|
|
FLD_LCORE,
|
|
|
|
_NUM_FLD
|
|
|
|
};
|
|
|
|
unsigned long int_fld[_NUM_FLD];
|
|
|
|
char *str_fld[_NUM_FLD];
|
|
|
|
int i;
|
|
|
|
unsigned size;
|
|
|
|
|
|
|
|
nb_lcore_params = 0;
|
|
|
|
|
|
|
|
while ((p = strchr(p0,'(')) != NULL) {
|
|
|
|
++p;
|
|
|
|
if((p0 = strchr(p,')')) == NULL)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
size = p0 - p;
|
|
|
|
if(size >= sizeof(s))
|
|
|
|
return -1;
|
|
|
|
|
2014-06-24 18:15:28 +00:00
|
|
|
snprintf(s, sizeof(s), "%.*s", size, p);
|
2012-09-04 12:54:00 +00:00
|
|
|
if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
|
|
|
|
return -1;
|
|
|
|
for (i = 0; i < _NUM_FLD; i++){
|
|
|
|
errno = 0;
|
|
|
|
int_fld[i] = strtoul(str_fld[i], &end, 0);
|
|
|
|
if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if (nb_lcore_params >= MAX_LCORE_PARAMS) {
|
|
|
|
printf("exceeded max number of lcore params: %hu\n",
|
|
|
|
nb_lcore_params);
|
|
|
|
return -1;
|
|
|
|
}
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
lcore_params_array[nb_lcore_params].port_id =
|
|
|
|
(uint8_t)int_fld[FLD_PORT];
|
|
|
|
lcore_params_array[nb_lcore_params].queue_id =
|
|
|
|
(uint8_t)int_fld[FLD_QUEUE];
|
|
|
|
lcore_params_array[nb_lcore_params].lcore_id =
|
|
|
|
(uint8_t)int_fld[FLD_LCORE];
|
2012-09-04 12:54:00 +00:00
|
|
|
++nb_lcore_params;
|
|
|
|
}
|
|
|
|
lcore_params = lcore_params_array;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-05-18 12:13:24 +00:00
|
|
|
static void
|
|
|
|
parse_eth_dest(const char *optarg)
|
|
|
|
{
|
2017-09-29 07:17:24 +00:00
|
|
|
uint16_t portid;
|
2015-05-18 12:13:24 +00:00
|
|
|
char *port_end;
|
|
|
|
uint8_t c, *dest, peer_addr[6];
|
|
|
|
|
|
|
|
errno = 0;
|
|
|
|
portid = strtoul(optarg, &port_end, 10);
|
|
|
|
if (errno != 0 || port_end == optarg || *port_end++ != ',')
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Invalid eth-dest: %s", optarg);
|
|
|
|
if (portid >= RTE_MAX_ETHPORTS)
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"eth-dest: port %d >= RTE_MAX_ETHPORTS(%d)\n",
|
|
|
|
portid, RTE_MAX_ETHPORTS);
|
|
|
|
|
|
|
|
if (cmdline_parse_etheraddr(NULL, port_end,
|
|
|
|
&peer_addr, sizeof(peer_addr)) < 0)
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Invalid ethernet address: %s\n",
|
|
|
|
port_end);
|
|
|
|
dest = (uint8_t *)&dest_eth_addr[portid];
|
|
|
|
for (c = 0; c < 6; c++)
|
|
|
|
dest[c] = peer_addr[c];
|
|
|
|
*(uint64_t *)(val_eth + portid) = dest_eth_addr[portid];
|
|
|
|
}
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
#define MAX_JUMBO_PKT_LEN 9600
|
|
|
|
#define MEMPOOL_CACHE_SIZE 256
|
|
|
|
|
2016-11-22 13:52:15 +00:00
|
|
|
static const char short_options[] =
|
|
|
|
"p:" /* portmask */
|
|
|
|
"P" /* promiscuous */
|
|
|
|
"L" /* enable long prefix match */
|
|
|
|
"E" /* enable exact match */
|
|
|
|
;
|
|
|
|
|
2013-06-03 00:00:00 +00:00
|
|
|
#define CMD_LINE_OPT_CONFIG "config"
|
2015-05-18 12:13:24 +00:00
|
|
|
#define CMD_LINE_OPT_ETH_DEST "eth-dest"
|
2013-06-03 00:00:00 +00:00
|
|
|
#define CMD_LINE_OPT_NO_NUMA "no-numa"
|
|
|
|
#define CMD_LINE_OPT_IPV6 "ipv6"
|
|
|
|
#define CMD_LINE_OPT_ENABLE_JUMBO "enable-jumbo"
|
|
|
|
#define CMD_LINE_OPT_HASH_ENTRY_NUM "hash-entry-num"
|
2016-03-25 00:47:46 +00:00
|
|
|
#define CMD_LINE_OPT_PARSE_PTYPE "parse-ptype"
|
2019-04-25 09:40:19 +00:00
|
|
|
#define CMD_LINE_OPT_PER_PORT_POOL "per-port-pool"
|
2016-11-22 13:52:15 +00:00
|
|
|
enum {
|
|
|
|
/* long options mapped to a short option */
|
|
|
|
|
|
|
|
/* first long only option value must be >= 256, so that we won't
|
|
|
|
* conflict with short options */
|
|
|
|
CMD_LINE_OPT_MIN_NUM = 256,
|
|
|
|
CMD_LINE_OPT_CONFIG_NUM,
|
|
|
|
CMD_LINE_OPT_ETH_DEST_NUM,
|
|
|
|
CMD_LINE_OPT_NO_NUMA_NUM,
|
|
|
|
CMD_LINE_OPT_IPV6_NUM,
|
|
|
|
CMD_LINE_OPT_ENABLE_JUMBO_NUM,
|
|
|
|
CMD_LINE_OPT_HASH_ENTRY_NUM_NUM,
|
|
|
|
CMD_LINE_OPT_PARSE_PTYPE_NUM,
|
2019-04-25 09:40:19 +00:00
|
|
|
CMD_LINE_OPT_PARSE_PER_PORT_POOL,
|
2016-11-22 13:52:15 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
static const struct option lgopts[] = {
|
|
|
|
{CMD_LINE_OPT_CONFIG, 1, 0, CMD_LINE_OPT_CONFIG_NUM},
|
|
|
|
{CMD_LINE_OPT_ETH_DEST, 1, 0, CMD_LINE_OPT_ETH_DEST_NUM},
|
|
|
|
{CMD_LINE_OPT_NO_NUMA, 0, 0, CMD_LINE_OPT_NO_NUMA_NUM},
|
|
|
|
{CMD_LINE_OPT_IPV6, 0, 0, CMD_LINE_OPT_IPV6_NUM},
|
|
|
|
{CMD_LINE_OPT_ENABLE_JUMBO, 0, 0, CMD_LINE_OPT_ENABLE_JUMBO_NUM},
|
|
|
|
{CMD_LINE_OPT_HASH_ENTRY_NUM, 1, 0, CMD_LINE_OPT_HASH_ENTRY_NUM_NUM},
|
|
|
|
{CMD_LINE_OPT_PARSE_PTYPE, 0, 0, CMD_LINE_OPT_PARSE_PTYPE_NUM},
|
2019-04-25 09:40:19 +00:00
|
|
|
{CMD_LINE_OPT_PER_PORT_POOL, 0, 0, CMD_LINE_OPT_PARSE_PER_PORT_POOL},
|
2016-11-22 13:52:15 +00:00
|
|
|
{NULL, 0, 0, 0}
|
|
|
|
};
|
2013-06-03 00:00:00 +00:00
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/*
|
|
|
|
* This expression is used to calculate the number of mbufs needed
|
|
|
|
* depending on user input, taking into account memory for rx and
|
|
|
|
* tx hardware rings, cache per lcore and mtable per port per lcore.
|
|
|
|
* RTE_MAX is used to ensure that NB_MBUF never goes below a minimum
|
|
|
|
* value of 8192
|
|
|
|
*/
|
2019-04-25 09:40:19 +00:00
|
|
|
#define NB_MBUF(nports) RTE_MAX( \
|
|
|
|
(nports*nb_rx_queue*nb_rxd + \
|
|
|
|
nports*nb_lcores*MAX_PKT_BURST + \
|
|
|
|
nports*n_tx_queue*nb_txd + \
|
2017-05-25 15:57:54 +00:00
|
|
|
nb_lcores*MEMPOOL_CACHE_SIZE), \
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
(unsigned)8192)
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
/* Parse the argument given in the command line of the application */
|
|
|
|
static int
|
|
|
|
parse_args(int argc, char **argv)
|
|
|
|
{
|
|
|
|
int opt, ret;
|
|
|
|
char **argvopt;
|
|
|
|
int option_index;
|
|
|
|
char *prgname = argv[0];
|
|
|
|
|
|
|
|
argvopt = argv;
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/* Error or normal output strings. */
|
2016-11-22 13:52:15 +00:00
|
|
|
while ((opt = getopt_long(argc, argvopt, short_options,
|
2012-09-04 12:54:00 +00:00
|
|
|
lgopts, &option_index)) != EOF) {
|
|
|
|
|
|
|
|
switch (opt) {
|
|
|
|
/* portmask */
|
|
|
|
case 'p':
|
|
|
|
enabled_port_mask = parse_portmask(optarg);
|
|
|
|
if (enabled_port_mask == 0) {
|
2017-12-11 23:12:58 +00:00
|
|
|
fprintf(stderr, "Invalid portmask\n");
|
2012-09-04 12:54:00 +00:00
|
|
|
print_usage(prgname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
break;
|
2016-11-22 13:52:15 +00:00
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
case 'P':
|
|
|
|
promiscuous_on = 1;
|
|
|
|
break;
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
case 'E':
|
|
|
|
l3fwd_em_on = 1;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'L':
|
|
|
|
l3fwd_lpm_on = 1;
|
|
|
|
break;
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
/* long options */
|
2016-11-22 13:52:15 +00:00
|
|
|
case CMD_LINE_OPT_CONFIG_NUM:
|
|
|
|
ret = parse_config(optarg);
|
|
|
|
if (ret) {
|
2017-12-11 23:12:58 +00:00
|
|
|
fprintf(stderr, "Invalid config\n");
|
2016-11-22 13:52:15 +00:00
|
|
|
print_usage(prgname);
|
|
|
|
return -1;
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
2016-11-22 13:52:15 +00:00
|
|
|
break;
|
2014-06-03 23:42:50 +00:00
|
|
|
|
2016-11-22 13:52:15 +00:00
|
|
|
case CMD_LINE_OPT_ETH_DEST_NUM:
|
|
|
|
parse_eth_dest(optarg);
|
|
|
|
break;
|
2013-06-03 00:00:00 +00:00
|
|
|
|
2016-11-22 13:52:15 +00:00
|
|
|
case CMD_LINE_OPT_NO_NUMA_NUM:
|
|
|
|
numa_on = 0;
|
|
|
|
break;
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
|
2016-11-22 13:52:15 +00:00
|
|
|
case CMD_LINE_OPT_IPV6_NUM:
|
|
|
|
ipv6 = 1;
|
|
|
|
break;
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
|
2016-11-22 13:52:15 +00:00
|
|
|
case CMD_LINE_OPT_ENABLE_JUMBO_NUM: {
|
2017-12-11 23:12:58 +00:00
|
|
|
const struct option lenopts = {
|
2016-11-22 13:52:15 +00:00
|
|
|
"max-pkt-len", required_argument, 0, 0
|
|
|
|
};
|
|
|
|
|
2017-12-26 09:23:04 +00:00
|
|
|
port_conf.rxmode.offloads |= DEV_RX_OFFLOAD_JUMBO_FRAME;
|
|
|
|
port_conf.txmode.offloads |= DEV_TX_OFFLOAD_MULTI_SEGS;
|
2016-11-22 13:52:15 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* if no max-pkt-len set, use the default
|
2019-05-21 16:13:05 +00:00
|
|
|
* value RTE_ETHER_MAX_LEN.
|
2016-11-22 13:52:15 +00:00
|
|
|
*/
|
|
|
|
if (getopt_long(argc, argvopt, "",
|
|
|
|
&lenopts, &option_index) == 0) {
|
|
|
|
ret = parse_max_pkt_len(optarg);
|
2017-12-11 23:12:58 +00:00
|
|
|
if (ret < 64 || ret > MAX_JUMBO_PKT_LEN) {
|
|
|
|
fprintf(stderr,
|
|
|
|
"invalid maximum packet length\n");
|
2013-06-03 00:00:00 +00:00
|
|
|
print_usage(prgname);
|
|
|
|
return -1;
|
|
|
|
}
|
2016-11-22 13:52:15 +00:00
|
|
|
port_conf.rxmode.max_rx_pkt_len = ret;
|
2013-06-03 00:00:00 +00:00
|
|
|
}
|
2016-11-22 13:52:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-03-25 00:47:46 +00:00
|
|
|
|
2016-11-22 13:52:15 +00:00
|
|
|
case CMD_LINE_OPT_HASH_ENTRY_NUM_NUM:
|
|
|
|
ret = parse_hash_entry_number(optarg);
|
|
|
|
if ((ret > 0) && (ret <= L3FWD_HASH_ENTRIES)) {
|
|
|
|
hash_entry_number = ret;
|
|
|
|
} else {
|
2017-12-11 23:12:58 +00:00
|
|
|
fprintf(stderr, "invalid hash entry number\n");
|
2016-11-22 13:52:15 +00:00
|
|
|
print_usage(prgname);
|
|
|
|
return -1;
|
2016-03-25 00:47:46 +00:00
|
|
|
}
|
2016-11-22 13:52:15 +00:00
|
|
|
break;
|
2016-03-25 00:47:46 +00:00
|
|
|
|
2016-11-22 13:52:15 +00:00
|
|
|
case CMD_LINE_OPT_PARSE_PTYPE_NUM:
|
|
|
|
printf("soft parse-ptype is enabled\n");
|
|
|
|
parse_ptype = 1;
|
2012-09-04 12:54:00 +00:00
|
|
|
break;
|
|
|
|
|
2019-04-25 09:40:19 +00:00
|
|
|
case CMD_LINE_OPT_PARSE_PER_PORT_POOL:
|
|
|
|
printf("per port buffer pool is enabled\n");
|
|
|
|
per_port_pool = 1;
|
|
|
|
break;
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
default:
|
|
|
|
print_usage(prgname);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/* If both LPM and EM are selected, return error. */
|
|
|
|
if (l3fwd_lpm_on && l3fwd_em_on) {
|
2017-12-11 23:12:58 +00:00
|
|
|
fprintf(stderr, "LPM and EM are mutually exclusive, select only one\n");
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Nothing is selected, pick longest-prefix match
|
|
|
|
* as default match.
|
|
|
|
*/
|
|
|
|
if (!l3fwd_lpm_on && !l3fwd_em_on) {
|
2017-12-11 23:12:58 +00:00
|
|
|
fprintf(stderr, "LPM or EM none selected, default LPM on\n");
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
l3fwd_lpm_on = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ipv6 and hash flags are valid only for
|
|
|
|
* exact macth, reset them to default for
|
|
|
|
* longest-prefix match.
|
|
|
|
*/
|
|
|
|
if (l3fwd_lpm_on) {
|
|
|
|
ipv6 = 0;
|
|
|
|
hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT;
|
|
|
|
}
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
if (optind >= 0)
|
|
|
|
argv[optind-1] = prgname;
|
|
|
|
|
|
|
|
ret = optind-1;
|
2017-02-14 22:09:41 +00:00
|
|
|
optind = 1; /* reset getopt lib */
|
2012-09-04 12:54:00 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-05-21 16:13:03 +00:00
|
|
|
print_ethaddr(const char *name, const struct rte_ether_addr *eth_addr)
|
2012-09-04 12:54:00 +00:00
|
|
|
{
|
2019-05-21 16:13:05 +00:00
|
|
|
char buf[RTE_ETHER_ADDR_FMT_SIZE];
|
|
|
|
rte_ether_format_addr(buf, RTE_ETHER_ADDR_FMT_SIZE, eth_addr);
|
2014-11-12 06:24:32 +00:00
|
|
|
printf("%s%s", name, buf);
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2019-04-25 09:40:19 +00:00
|
|
|
init_mem(uint16_t portid, unsigned int nb_mbuf)
|
2012-09-04 12:54:00 +00:00
|
|
|
{
|
|
|
|
struct lcore_conf *qconf;
|
|
|
|
int socketid;
|
|
|
|
unsigned lcore_id;
|
|
|
|
char s[64];
|
|
|
|
|
|
|
|
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
|
|
|
|
if (rte_lcore_is_enabled(lcore_id) == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (numa_on)
|
|
|
|
socketid = rte_lcore_to_socket_id(lcore_id);
|
|
|
|
else
|
|
|
|
socketid = 0;
|
|
|
|
|
|
|
|
if (socketid >= NB_SOCKETS) {
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Socket %d of lcore %u is out of range %d\n",
|
2012-09-04 12:54:00 +00:00
|
|
|
socketid, lcore_id, NB_SOCKETS);
|
|
|
|
}
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
|
2019-04-25 09:40:19 +00:00
|
|
|
if (pktmbuf_pool[portid][socketid] == NULL) {
|
|
|
|
snprintf(s, sizeof(s), "mbuf_pool_%d:%d",
|
|
|
|
portid, socketid);
|
|
|
|
pktmbuf_pool[portid][socketid] =
|
2015-04-22 09:57:24 +00:00
|
|
|
rte_pktmbuf_pool_create(s, nb_mbuf,
|
2015-04-29 23:31:51 +00:00
|
|
|
MEMPOOL_CACHE_SIZE, 0,
|
|
|
|
RTE_MBUF_DEFAULT_BUF_SIZE, socketid);
|
2019-04-25 09:40:19 +00:00
|
|
|
if (pktmbuf_pool[portid][socketid] == NULL)
|
2012-09-04 12:54:00 +00:00
|
|
|
rte_exit(EXIT_FAILURE,
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
"Cannot init mbuf pool on socket %d\n",
|
|
|
|
socketid);
|
2012-09-04 12:54:00 +00:00
|
|
|
else
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
printf("Allocated mbuf pool on socket %d\n",
|
|
|
|
socketid);
|
2012-09-04 12:54:00 +00:00
|
|
|
|
2019-04-25 09:40:19 +00:00
|
|
|
/* Setup either LPM or EM(f.e Hash). But, only once per
|
|
|
|
* available socket.
|
|
|
|
*/
|
|
|
|
if (!lkp_per_socket[socketid]) {
|
|
|
|
l3fwd_lkp.setup(socketid);
|
|
|
|
lkp_per_socket[socketid] = 1;
|
|
|
|
}
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
qconf = &lcore_conf[lcore_id];
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
qconf->ipv4_lookup_struct =
|
|
|
|
l3fwd_lkp.get_ipv4_lookup_struct(socketid);
|
|
|
|
qconf->ipv6_lookup_struct =
|
|
|
|
l3fwd_lkp.get_ipv6_lookup_struct(socketid);
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-12-19 23:00:00 +00:00
|
|
|
/* Check the link status of all ports in up to 9s, and print them finally */
|
|
|
|
static void
|
2018-04-05 15:33:20 +00:00
|
|
|
check_all_ports_link_status(uint32_t port_mask)
|
2012-12-19 23:00:00 +00:00
|
|
|
{
|
|
|
|
#define CHECK_INTERVAL 100 /* 100ms */
|
|
|
|
#define MAX_CHECK_TIME 90 /* 9s (90 * 100ms) in total */
|
2017-09-29 07:17:24 +00:00
|
|
|
uint16_t portid;
|
|
|
|
uint8_t count, all_ports_up, print_flag = 0;
|
2012-12-19 23:00:00 +00:00
|
|
|
struct rte_eth_link link;
|
|
|
|
|
|
|
|
printf("\nChecking link status");
|
|
|
|
fflush(stdout);
|
|
|
|
for (count = 0; count <= MAX_CHECK_TIME; count++) {
|
2015-12-30 21:59:51 +00:00
|
|
|
if (force_quit)
|
|
|
|
return;
|
2012-12-19 23:00:00 +00:00
|
|
|
all_ports_up = 1;
|
2018-04-05 15:33:20 +00:00
|
|
|
RTE_ETH_FOREACH_DEV(portid) {
|
2015-12-30 21:59:51 +00:00
|
|
|
if (force_quit)
|
|
|
|
return;
|
2012-12-19 23:00:00 +00:00
|
|
|
if ((port_mask & (1 << portid)) == 0)
|
|
|
|
continue;
|
|
|
|
memset(&link, 0, sizeof(link));
|
|
|
|
rte_eth_link_get_nowait(portid, &link);
|
|
|
|
/* print link status if flag set */
|
|
|
|
if (print_flag == 1) {
|
|
|
|
if (link.link_status)
|
2017-09-29 07:17:24 +00:00
|
|
|
printf(
|
|
|
|
"Port%d Link Up. Speed %u Mbps -%s\n",
|
|
|
|
portid, link.link_speed,
|
2012-12-19 23:00:00 +00:00
|
|
|
(link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
|
|
|
|
("full-duplex") : ("half-duplex\n"));
|
|
|
|
else
|
2017-09-29 07:17:24 +00:00
|
|
|
printf("Port %d Link Down\n", portid);
|
2012-12-19 23:00:00 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* clear all_ports_up flag if any link down */
|
2016-03-31 22:12:24 +00:00
|
|
|
if (link.link_status == ETH_LINK_DOWN) {
|
2012-12-19 23:00:00 +00:00
|
|
|
all_ports_up = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* after finally printing all link status, get out */
|
|
|
|
if (print_flag == 1)
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (all_ports_up == 0) {
|
|
|
|
printf(".");
|
|
|
|
fflush(stdout);
|
|
|
|
rte_delay_ms(CHECK_INTERVAL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set the print_flag if all ports up or timeout */
|
|
|
|
if (all_ports_up == 1 || count == (MAX_CHECK_TIME - 1)) {
|
|
|
|
print_flag = 1;
|
|
|
|
printf("done\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-30 21:59:51 +00:00
|
|
|
static void
|
|
|
|
signal_handler(int signum)
|
|
|
|
{
|
|
|
|
if (signum == SIGINT || signum == SIGTERM) {
|
|
|
|
printf("\n\nSignal %d received, preparing to exit...\n",
|
|
|
|
signum);
|
|
|
|
force_quit = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-25 00:47:46 +00:00
|
|
|
static int
|
2017-09-29 07:17:24 +00:00
|
|
|
prepare_ptype_parser(uint16_t portid, uint16_t queueid)
|
2016-03-25 00:47:46 +00:00
|
|
|
{
|
|
|
|
if (parse_ptype) {
|
|
|
|
printf("Port %d: softly parse packet type info\n", portid);
|
|
|
|
if (rte_eth_add_rx_callback(portid, queueid,
|
|
|
|
l3fwd_lkp.cb_parse_ptype,
|
|
|
|
NULL))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
printf("Failed to add rx callback: port=%d\n", portid);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (l3fwd_lkp.check_ptype(portid))
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
printf("port %d cannot parse packet type, please add --%s\n",
|
|
|
|
portid, CMD_LINE_OPT_PARSE_PTYPE);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
int
|
2014-09-26 14:04:02 +00:00
|
|
|
main(int argc, char **argv)
|
2012-09-04 12:54:00 +00:00
|
|
|
{
|
|
|
|
struct lcore_conf *qconf;
|
2014-10-01 09:49:05 +00:00
|
|
|
struct rte_eth_dev_info dev_info;
|
|
|
|
struct rte_eth_txconf *txconf;
|
2012-09-04 12:54:00 +00:00
|
|
|
int ret;
|
|
|
|
unsigned nb_ports;
|
2017-09-29 07:17:24 +00:00
|
|
|
uint16_t queueid, portid;
|
2012-09-04 12:54:00 +00:00
|
|
|
unsigned lcore_id;
|
|
|
|
uint32_t n_tx_queue, nb_lcores;
|
2017-09-29 07:17:24 +00:00
|
|
|
uint8_t nb_rx_queue, queue, socketid;
|
2012-09-04 12:54:00 +00:00
|
|
|
|
|
|
|
/* init EAL */
|
|
|
|
ret = rte_eal_init(argc, argv);
|
|
|
|
if (ret < 0)
|
|
|
|
rte_exit(EXIT_FAILURE, "Invalid EAL parameters\n");
|
|
|
|
argc -= ret;
|
|
|
|
argv += ret;
|
|
|
|
|
2015-12-30 21:59:51 +00:00
|
|
|
force_quit = false;
|
|
|
|
signal(SIGINT, signal_handler);
|
|
|
|
signal(SIGTERM, signal_handler);
|
|
|
|
|
2015-05-18 12:13:24 +00:00
|
|
|
/* pre-init dst MACs for all ports to 02:00:00:00:00:xx */
|
|
|
|
for (portid = 0; portid < RTE_MAX_ETHPORTS; portid++) {
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
dest_eth_addr[portid] =
|
2019-05-21 16:13:05 +00:00
|
|
|
RTE_ETHER_LOCAL_ADMIN_ADDR + ((uint64_t)portid << 40);
|
2015-05-18 12:13:24 +00:00
|
|
|
*(uint64_t *)(val_eth + portid) = dest_eth_addr[portid];
|
|
|
|
}
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
/* parse application arguments (after the EAL ones) */
|
|
|
|
ret = parse_args(argc, argv);
|
|
|
|
if (ret < 0)
|
|
|
|
rte_exit(EXIT_FAILURE, "Invalid L3FWD parameters\n");
|
|
|
|
|
|
|
|
if (check_lcore_params() < 0)
|
|
|
|
rte_exit(EXIT_FAILURE, "check_lcore_params failed\n");
|
|
|
|
|
|
|
|
ret = init_lcore_rx_queues();
|
|
|
|
if (ret < 0)
|
|
|
|
rte_exit(EXIT_FAILURE, "init_lcore_rx_queues failed\n");
|
|
|
|
|
2018-04-05 15:33:22 +00:00
|
|
|
nb_ports = rte_eth_dev_count_avail();
|
2012-09-04 12:54:00 +00:00
|
|
|
|
2018-04-05 15:33:21 +00:00
|
|
|
if (check_port_config() < 0)
|
2012-09-04 12:54:00 +00:00
|
|
|
rte_exit(EXIT_FAILURE, "check_port_config failed\n");
|
|
|
|
|
|
|
|
nb_lcores = rte_lcore_count();
|
|
|
|
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
/* Setup function pointers for lookup method. */
|
|
|
|
setup_l3fwd_lookup_tables();
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
/* initialize all ports */
|
2018-04-05 15:33:20 +00:00
|
|
|
RTE_ETH_FOREACH_DEV(portid) {
|
2017-12-26 09:23:04 +00:00
|
|
|
struct rte_eth_conf local_port_conf = port_conf;
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
/* skip ports that are not enabled */
|
|
|
|
if ((enabled_port_mask & (1 << portid)) == 0) {
|
|
|
|
printf("\nSkipping disabled port %d\n", portid);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* init port */
|
|
|
|
printf("Initializing port %d ... ", portid );
|
|
|
|
fflush(stdout);
|
|
|
|
|
|
|
|
nb_rx_queue = get_port_n_rx_queues(portid);
|
|
|
|
n_tx_queue = nb_lcores;
|
|
|
|
if (n_tx_queue > MAX_TX_QUEUE_PER_PORT)
|
|
|
|
n_tx_queue = MAX_TX_QUEUE_PER_PORT;
|
|
|
|
printf("Creating queues: nb_rxq=%d nb_txq=%u... ",
|
|
|
|
nb_rx_queue, (unsigned)n_tx_queue );
|
2017-12-26 09:23:04 +00:00
|
|
|
|
|
|
|
rte_eth_dev_info_get(portid, &dev_info);
|
|
|
|
if (dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MBUF_FAST_FREE)
|
|
|
|
local_port_conf.txmode.offloads |=
|
|
|
|
DEV_TX_OFFLOAD_MBUF_FAST_FREE;
|
2018-07-04 20:02:21 +00:00
|
|
|
|
|
|
|
local_port_conf.rx_adv_conf.rss_conf.rss_hf &=
|
|
|
|
dev_info.flow_type_rss_offloads;
|
|
|
|
if (local_port_conf.rx_adv_conf.rss_conf.rss_hf !=
|
|
|
|
port_conf.rx_adv_conf.rss_conf.rss_hf) {
|
|
|
|
printf("Port %u modified RSS hash function based on hardware support,"
|
|
|
|
"requested:%#"PRIx64" configured:%#"PRIx64"\n",
|
|
|
|
portid,
|
|
|
|
port_conf.rx_adv_conf.rss_conf.rss_hf,
|
|
|
|
local_port_conf.rx_adv_conf.rss_conf.rss_hf);
|
|
|
|
}
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
ret = rte_eth_dev_configure(portid, nb_rx_queue,
|
2017-12-26 09:23:04 +00:00
|
|
|
(uint16_t)n_tx_queue, &local_port_conf);
|
2012-09-04 12:54:00 +00:00
|
|
|
if (ret < 0)
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Cannot configure device: err=%d, port=%d\n",
|
2012-09-04 12:54:00 +00:00
|
|
|
ret, portid);
|
|
|
|
|
2017-05-25 15:57:54 +00:00
|
|
|
ret = rte_eth_dev_adjust_nb_rx_tx_desc(portid, &nb_rxd,
|
|
|
|
&nb_txd);
|
|
|
|
if (ret < 0)
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Cannot adjust number of descriptors: err=%d, "
|
|
|
|
"port=%d\n", ret, portid);
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
rte_eth_macaddr_get(portid, &ports_eth_addr[portid]);
|
|
|
|
print_ethaddr(" Address:", &ports_eth_addr[portid]);
|
|
|
|
printf(", ");
|
2015-05-18 12:13:24 +00:00
|
|
|
print_ethaddr("Destination:",
|
2019-05-21 16:13:03 +00:00
|
|
|
(const struct rte_ether_addr *)&dest_eth_addr[portid]);
|
2015-05-18 12:13:24 +00:00
|
|
|
printf(", ");
|
2012-09-04 12:54:00 +00:00
|
|
|
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
/*
|
2015-05-18 12:13:24 +00:00
|
|
|
* prepare src MACs for each port.
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
*/
|
2019-05-21 16:13:04 +00:00
|
|
|
rte_ether_addr_copy(&ports_eth_addr[portid],
|
2019-05-21 16:13:03 +00:00
|
|
|
(struct rte_ether_addr *)(val_eth + portid) + 1);
|
examples/l3fwd: reorganise and optimize LPM code path
With latest HW and optimised RX/TX path there is a huge gap between
tespmd iofwd and l3fwd performance results.
So there is an attempt to optimise l3fwd LPM code path and reduce the gap:
- Instead of processing each input packet up to completion -
divide packet processing into several stages and perform
stage by stage for the whole burst.
- Unroll things by the factor of 4 whenever possible.
- Use SSE instincts for some operations (bswap, replace MAC addresses, etc).
- Avoid TX packet buffering whenever possible.
- Move some checks from RX/TX into setup phase.
Note that new(optimized) code path can be switched on/off by setting
ENABLE_MULTI_BUFFER_OPTIMIZE macro to 1/0.
Some performance data:
SUT: dual-socket board IVB 2.8GHz, 2x1GB pages.
4 ports on 4 NICs (all at socket 0) connected to the traffic generator.
kernel: 3.11.3-201.fc19.x86_64, gcc: 4.8.2.
64B packets, using the packet flooding method.
All 4 ports are managed by one logical core:
Optimised scalar PMD RX/TX was used.
DIFF % (NEW-OLD)
IPV4-CONT-BURST: +23%
IPV6-CONT-BURST : +13%
IPV4/IPV6-CONT-BURST: +8%
IPV4-4STREAMSX8: +7%
IPV4-4STREAMSX1: -2%
Test cases description:
IPV4-CONT-BURST - IPV4 packets all packets from the one input port
are destined for the same output port.
IPV6-CONT-BURST - IPV6 packets all packets from the one input port
are destined for the same output port.
IPV4/IPV6-CONT-BURST - mix of the first 2 with interleave=1
(e.g: IPV4,IPV6,IPV4,IPV6, ...)
IPV4-4STREAMSX1 - 4 streams of IPV4 packets, where all packets
from same stream are destined for the same output port
(e.g: IPV4_DST_P0, IPV4_DST_P1, IPV4_DST_P2, IPV4_DST_P3, IPV4_DST_P0, ...)
IPV4-4STREAMSX8 - same as above but packets for each stream
are coming in groups of 8
(e.g: IPV4_DST_P0 X 8, IPV4_DST_P1 X 8, IPV4_DST_P2 X 8, IPV4_DST_P3 X 8,
IPV4_DST_P0 X 8, ...)
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Tested-by: Waterman Cao <waterman.cao@intel.com>
Acked-by: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
2014-06-11 13:38:46 +00:00
|
|
|
|
2012-12-19 23:00:00 +00:00
|
|
|
/* init memory */
|
2019-04-25 09:40:19 +00:00
|
|
|
if (!per_port_pool) {
|
|
|
|
/* portid = 0; this is *not* signifying the first port,
|
|
|
|
* rather, it signifies that portid is ignored.
|
|
|
|
*/
|
|
|
|
ret = init_mem(0, NB_MBUF(nb_ports));
|
|
|
|
} else {
|
|
|
|
ret = init_mem(portid, NB_MBUF(1));
|
|
|
|
}
|
2012-12-19 23:00:00 +00:00
|
|
|
if (ret < 0)
|
|
|
|
rte_exit(EXIT_FAILURE, "init_mem failed\n");
|
2012-09-04 12:54:00 +00:00
|
|
|
|
|
|
|
/* init one TX queue per couple (lcore,port) */
|
|
|
|
queueid = 0;
|
|
|
|
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
|
|
|
|
if (rte_lcore_is_enabled(lcore_id) == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
if (numa_on)
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
socketid =
|
|
|
|
(uint8_t)rte_lcore_to_socket_id(lcore_id);
|
2012-09-04 12:54:00 +00:00
|
|
|
else
|
|
|
|
socketid = 0;
|
|
|
|
|
|
|
|
printf("txq=%u,%d,%d ", lcore_id, queueid, socketid);
|
|
|
|
fflush(stdout);
|
2014-10-01 09:49:05 +00:00
|
|
|
|
|
|
|
txconf = &dev_info.default_txconf;
|
2017-12-26 09:23:04 +00:00
|
|
|
txconf->offloads = local_port_conf.txmode.offloads;
|
2012-09-04 12:54:00 +00:00
|
|
|
ret = rte_eth_tx_queue_setup(portid, queueid, nb_txd,
|
2014-10-01 09:49:05 +00:00
|
|
|
socketid, txconf);
|
2012-09-04 12:54:00 +00:00
|
|
|
if (ret < 0)
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"rte_eth_tx_queue_setup: err=%d, "
|
2012-09-04 12:54:00 +00:00
|
|
|
"port=%d\n", ret, portid);
|
|
|
|
|
|
|
|
qconf = &lcore_conf[lcore_id];
|
|
|
|
qconf->tx_queue_id[portid] = queueid;
|
|
|
|
queueid++;
|
2016-03-18 13:31:46 +00:00
|
|
|
|
|
|
|
qconf->tx_port_id[qconf->n_tx_port] = portid;
|
2016-03-31 13:38:08 +00:00
|
|
|
qconf->n_tx_port++;
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
|
|
|
|
if (rte_lcore_is_enabled(lcore_id) == 0)
|
|
|
|
continue;
|
|
|
|
qconf = &lcore_conf[lcore_id];
|
|
|
|
printf("\nInitializing rx queues on lcore %u ... ", lcore_id );
|
|
|
|
fflush(stdout);
|
|
|
|
/* init RX queues */
|
|
|
|
for(queue = 0; queue < qconf->n_rx_queue; ++queue) {
|
2017-12-26 09:23:04 +00:00
|
|
|
struct rte_eth_dev *dev;
|
|
|
|
struct rte_eth_conf *conf;
|
|
|
|
struct rte_eth_rxconf rxq_conf;
|
|
|
|
|
2012-09-04 12:54:00 +00:00
|
|
|
portid = qconf->rx_queue_list[queue].port_id;
|
|
|
|
queueid = qconf->rx_queue_list[queue].queue_id;
|
2017-12-26 09:23:04 +00:00
|
|
|
dev = &rte_eth_devices[portid];
|
|
|
|
conf = &dev->data->dev_conf;
|
2012-09-04 12:54:00 +00:00
|
|
|
|
|
|
|
if (numa_on)
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
socketid =
|
|
|
|
(uint8_t)rte_lcore_to_socket_id(lcore_id);
|
2012-09-04 12:54:00 +00:00
|
|
|
else
|
|
|
|
socketid = 0;
|
|
|
|
|
|
|
|
printf("rxq=%d,%d,%d ", portid, queueid, socketid);
|
|
|
|
fflush(stdout);
|
|
|
|
|
2017-12-26 09:23:04 +00:00
|
|
|
rte_eth_dev_info_get(portid, &dev_info);
|
|
|
|
rxq_conf = dev_info.default_rxconf;
|
|
|
|
rxq_conf.offloads = conf->rxmode.offloads;
|
2019-04-25 09:40:19 +00:00
|
|
|
if (!per_port_pool)
|
|
|
|
ret = rte_eth_rx_queue_setup(portid, queueid,
|
|
|
|
nb_rxd, socketid,
|
|
|
|
&rxq_conf,
|
|
|
|
pktmbuf_pool[0][socketid]);
|
|
|
|
else
|
|
|
|
ret = rte_eth_rx_queue_setup(portid, queueid,
|
|
|
|
nb_rxd, socketid,
|
|
|
|
&rxq_conf,
|
|
|
|
pktmbuf_pool[portid][socketid]);
|
2012-09-04 12:54:00 +00:00
|
|
|
if (ret < 0)
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"rte_eth_rx_queue_setup: err=%d, port=%d\n",
|
|
|
|
ret, portid);
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
/* start ports */
|
2018-04-05 15:33:20 +00:00
|
|
|
RTE_ETH_FOREACH_DEV(portid) {
|
2012-09-04 12:54:00 +00:00
|
|
|
if ((enabled_port_mask & (1 << portid)) == 0) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
/* Start device */
|
|
|
|
ret = rte_eth_dev_start(portid);
|
|
|
|
if (ret < 0)
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"rte_eth_dev_start: err=%d, port=%d\n",
|
2012-09-04 12:54:00 +00:00
|
|
|
ret, portid);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* If enabled, put device in promiscuous mode.
|
|
|
|
* This allows IO forwarding mode to forward packets
|
|
|
|
* to itself through 2 cross-connected ports of the
|
|
|
|
* target machine.
|
|
|
|
*/
|
|
|
|
if (promiscuous_on)
|
|
|
|
rte_eth_promiscuous_enable(portid);
|
|
|
|
}
|
|
|
|
|
2016-03-25 00:47:46 +00:00
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
|
|
|
|
if (rte_lcore_is_enabled(lcore_id) == 0)
|
|
|
|
continue;
|
|
|
|
qconf = &lcore_conf[lcore_id];
|
|
|
|
for (queue = 0; queue < qconf->n_rx_queue; ++queue) {
|
|
|
|
portid = qconf->rx_queue_list[queue].port_id;
|
|
|
|
queueid = qconf->rx_queue_list[queue].queue_id;
|
|
|
|
if (prepare_ptype_parser(portid, queueid) == 0)
|
|
|
|
rte_exit(EXIT_FAILURE, "ptype check fails\n");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2018-04-05 15:33:20 +00:00
|
|
|
check_all_ports_link_status(enabled_port_mask);
|
2012-12-19 23:00:00 +00:00
|
|
|
|
2015-12-30 21:59:51 +00:00
|
|
|
ret = 0;
|
2012-09-04 12:54:00 +00:00
|
|
|
/* launch per-lcore init on every lcore */
|
examples/l3fwd: modularize
The main problem with l3fwd is that it is too monolithic with everything
being in one file, and the various options all controlled by compile time
flags. This means that it's hard to read and understand, and when making
any changes, you need to go to a lot of work to try and ensure you cover
all the code paths, since a compile of the app will not touch large parts
of the l3fwd codebase.
Following changes were done to fix the issues mentioned above
- Split out the various lpm and hash specific functionality into separate
files, so that l3fwd code has one file for common code e.g. args
processing, mempool creation, and then individual files for the various
forwarding approaches.
Following are new file lists
main.c (Common code for args processing, memppol creation, etc)
l3fwd_em.c (Hash/Exact match aka 'EM' functionality)
l3fwd_em_sse.h (SSE4_1 buffer optimizated 'EM' code)
l3fwd_lpm.c (Longest Prefix Match aka 'LPM' functionality)
l3fwd_lpm_sse.h (SSE4_1 buffer optimizated 'LPM' code)
l3fwd.h (Common include for 'EM' and 'LPM')
- The choosing of the lpm/hash path should be done at runtime, not
compile time, via a command-line argument. This will ensure that
both code paths get compiled in a single go
Following examples show runtime options provided
Select 'LPM' or 'EM' based on run time selection f.e.
> l3fwd -c 0x1 -n 1 -- -p 0x1 -E ... (EM)
> l3fwd -c 0x1 -n 1 -- -p 0x1 -L ... (LPM)
Options "E" and "L" are mutualy-exclusive.
If none selected, "L" is default.
Signed-off-by: Ravi Kerur <rkerur@gmail.com>
Signed-off-by: Piotr Azarewicz <piotrx.t.azarewicz@intel.com>
Tested-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Tomasz Kulasek <tomaszx.kulasek@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
2016-02-25 10:24:24 +00:00
|
|
|
rte_eal_mp_remote_launch(l3fwd_lkp.main_loop, NULL, CALL_MASTER);
|
2012-09-04 12:54:00 +00:00
|
|
|
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
|
2015-12-30 21:59:51 +00:00
|
|
|
if (rte_eal_wait_lcore(lcore_id) < 0) {
|
|
|
|
ret = -1;
|
|
|
|
break;
|
|
|
|
}
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|
|
|
|
|
2015-12-30 21:59:51 +00:00
|
|
|
/* stop ports */
|
2018-04-05 15:33:20 +00:00
|
|
|
RTE_ETH_FOREACH_DEV(portid) {
|
2015-12-30 21:59:51 +00:00
|
|
|
if ((enabled_port_mask & (1 << portid)) == 0)
|
|
|
|
continue;
|
|
|
|
printf("Closing port %d...", portid);
|
|
|
|
rte_eth_dev_stop(portid);
|
|
|
|
rte_eth_dev_close(portid);
|
|
|
|
printf(" Done\n");
|
|
|
|
}
|
|
|
|
printf("Bye...\n");
|
|
|
|
|
|
|
|
return ret;
|
2012-09-04 12:54:00 +00:00
|
|
|
}
|