2017-12-19 15:49:02 +00:00
|
|
|
/* SPDX-License-Identifier: BSD-3-Clause
|
|
|
|
* Copyright(c) 2010-2016 Intel Corporation
|
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
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef __L3_FWD_H__
|
|
|
|
#define __L3_FWD_H__
|
|
|
|
|
2016-03-10 16:06:22 +00:00
|
|
|
#include <rte_vect.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
|
|
|
#define DO_RFC_1812_CHECKS
|
|
|
|
|
|
|
|
#define RTE_LOGTYPE_L3FWD RTE_LOGTYPE_USER1
|
|
|
|
|
2016-03-18 13:31:46 +00:00
|
|
|
#if !defined(NO_HASH_MULTI_LOOKUP) && defined(RTE_MACHINE_CPUFLAG_NEON)
|
|
|
|
#define NO_HASH_MULTI_LOOKUP 1
|
|
|
|
#endif
|
|
|
|
|
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_PKT_BURST 32
|
|
|
|
#define BURST_TX_DRAIN_US 100 /* TX drain every ~100us */
|
|
|
|
|
|
|
|
#define MAX_RX_QUEUE_PER_LCORE 16
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Try to avoid TX buffering if we have at least MAX_TX_BURST packets to send.
|
|
|
|
*/
|
|
|
|
#define MAX_TX_BURST (MAX_PKT_BURST / 2)
|
|
|
|
|
|
|
|
#define NB_SOCKETS 8
|
|
|
|
|
|
|
|
/* Configure how many packets ahead to prefetch, when reading packets */
|
|
|
|
#define PREFETCH_OFFSET 3
|
|
|
|
|
2016-02-29 10:33:07 +00:00
|
|
|
/* Used to mark destination port as 'invalid'. */
|
|
|
|
#define BAD_PORT ((uint16_t)-1)
|
|
|
|
|
|
|
|
#define FWDSTEP 4
|
|
|
|
|
|
|
|
/* replace first 12B of the ethernet header. */
|
|
|
|
#define MASK_ETH 0x3f
|
|
|
|
|
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
|
|
|
/* Hash parameters. */
|
2016-08-23 14:54:40 +00:00
|
|
|
#ifdef RTE_ARCH_64
|
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
|
|
|
/* default to 4 million hash entries (approx) */
|
|
|
|
#define L3FWD_HASH_ENTRIES (1024*1024*4)
|
|
|
|
#else
|
|
|
|
/* 32-bit has less address-space for hugepage memory, limit to 1M entries */
|
|
|
|
#define L3FWD_HASH_ENTRIES (1024*1024*1)
|
|
|
|
#endif
|
|
|
|
#define HASH_ENTRY_NUMBER_DEFAULT 4
|
|
|
|
|
|
|
|
struct mbuf_table {
|
|
|
|
uint16_t len;
|
|
|
|
struct rte_mbuf *m_table[MAX_PKT_BURST];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct lcore_rx_queue {
|
2017-09-29 07:17:24 +00:00
|
|
|
uint16_t port_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
|
|
|
uint8_t queue_id;
|
|
|
|
} __rte_cache_aligned;
|
|
|
|
|
|
|
|
struct lcore_conf {
|
|
|
|
uint16_t n_rx_queue;
|
|
|
|
struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE];
|
2016-03-18 13:31:46 +00:00
|
|
|
uint16_t n_tx_port;
|
|
|
|
uint16_t tx_port_id[RTE_MAX_ETHPORTS];
|
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
|
|
|
uint16_t tx_queue_id[RTE_MAX_ETHPORTS];
|
|
|
|
struct mbuf_table tx_mbufs[RTE_MAX_ETHPORTS];
|
|
|
|
void *ipv4_lookup_struct;
|
|
|
|
void *ipv6_lookup_struct;
|
|
|
|
} __rte_cache_aligned;
|
|
|
|
|
|
|
|
extern volatile bool force_quit;
|
|
|
|
|
|
|
|
/* ethernet addresses of ports */
|
|
|
|
extern uint64_t dest_eth_addr[RTE_MAX_ETHPORTS];
|
|
|
|
extern struct ether_addr ports_eth_addr[RTE_MAX_ETHPORTS];
|
|
|
|
|
|
|
|
/* mask of enabled ports */
|
|
|
|
extern uint32_t enabled_port_mask;
|
|
|
|
|
|
|
|
/* Used only in exact match mode. */
|
|
|
|
extern int ipv6; /**< ipv6 is false by default. */
|
|
|
|
extern uint32_t hash_entry_number;
|
|
|
|
|
2016-03-10 16:06:22 +00:00
|
|
|
extern xmm_t val_eth[RTE_MAX_ETHPORTS];
|
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
|
|
|
|
|
|
|
extern struct lcore_conf lcore_conf[RTE_MAX_LCORE];
|
|
|
|
|
|
|
|
/* Send burst of packets on an output interface */
|
|
|
|
static inline int
|
2017-09-29 07:17:24 +00:00
|
|
|
send_burst(struct lcore_conf *qconf, uint16_t n, uint16_t port)
|
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 rte_mbuf **m_table;
|
|
|
|
int ret;
|
|
|
|
uint16_t queueid;
|
|
|
|
|
|
|
|
queueid = qconf->tx_queue_id[port];
|
|
|
|
m_table = (struct rte_mbuf **)qconf->tx_mbufs[port].m_table;
|
|
|
|
|
|
|
|
ret = rte_eth_tx_burst(port, queueid, m_table, n);
|
|
|
|
if (unlikely(ret < n)) {
|
|
|
|
do {
|
|
|
|
rte_pktmbuf_free(m_table[ret]);
|
|
|
|
} while (++ret < n);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Enqueue a single packet, and send burst if queue is filled */
|
|
|
|
static inline int
|
|
|
|
send_single_packet(struct lcore_conf *qconf,
|
2017-09-29 07:17:24 +00:00
|
|
|
struct rte_mbuf *m, uint16_t port)
|
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
|
|
|
{
|
|
|
|
uint16_t len;
|
|
|
|
|
|
|
|
len = qconf->tx_mbufs[port].len;
|
|
|
|
qconf->tx_mbufs[port].m_table[len] = m;
|
|
|
|
len++;
|
|
|
|
|
|
|
|
/* enough pkts to be sent */
|
|
|
|
if (unlikely(len == MAX_PKT_BURST)) {
|
|
|
|
send_burst(qconf, MAX_PKT_BURST, port);
|
|
|
|
len = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
qconf->tx_mbufs[port].len = len;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DO_RFC_1812_CHECKS
|
|
|
|
static inline int
|
|
|
|
is_valid_ipv4_pkt(struct ipv4_hdr *pkt, uint32_t link_len)
|
|
|
|
{
|
|
|
|
/* From http://www.rfc-editor.org/rfc/rfc1812.txt section 5.2.2 */
|
|
|
|
/*
|
|
|
|
* 1. The packet length reported by the Link Layer must be large
|
|
|
|
* enough to hold the minimum length legal IP datagram (20 bytes).
|
|
|
|
*/
|
|
|
|
if (link_len < sizeof(struct ipv4_hdr))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
/* 2. The IP checksum must be correct. */
|
|
|
|
/* this is checked in H/W */
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 3. The IP version number must be 4. If the version number is not 4
|
|
|
|
* then the packet may be another version of IP, such as IPng or
|
|
|
|
* ST-II.
|
|
|
|
*/
|
|
|
|
if (((pkt->version_ihl) >> 4) != 4)
|
|
|
|
return -3;
|
|
|
|
/*
|
|
|
|
* 4. The IP header length field must be large enough to hold the
|
|
|
|
* minimum length legal IP datagram (20 bytes = 5 words).
|
|
|
|
*/
|
|
|
|
if ((pkt->version_ihl & 0xf) < 5)
|
|
|
|
return -4;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 5. The IP total length field must be large enough to hold the IP
|
|
|
|
* datagram header, whose length is specified in the IP header length
|
|
|
|
* field.
|
|
|
|
*/
|
|
|
|
if (rte_cpu_to_be_16(pkt->total_length) < sizeof(struct ipv4_hdr))
|
|
|
|
return -5;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
#endif /* DO_RFC_1812_CHECKS */
|
|
|
|
|
|
|
|
/* Function pointers for LPM or EM functionality. */
|
|
|
|
void
|
|
|
|
setup_lpm(const int socketid);
|
|
|
|
|
|
|
|
void
|
|
|
|
setup_hash(const int socketid);
|
|
|
|
|
2016-03-25 00:47:46 +00:00
|
|
|
int
|
|
|
|
em_check_ptype(int portid);
|
|
|
|
|
|
|
|
int
|
|
|
|
lpm_check_ptype(int portid);
|
|
|
|
|
|
|
|
uint16_t
|
2017-09-29 07:17:24 +00:00
|
|
|
em_cb_parse_ptype(uint16_t port, uint16_t queue, struct rte_mbuf *pkts[],
|
2016-03-25 00:47:46 +00:00
|
|
|
uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
|
|
|
|
|
|
|
|
uint16_t
|
2017-09-29 07:17:24 +00:00
|
|
|
lpm_cb_parse_ptype(uint16_t port, uint16_t queue, struct rte_mbuf *pkts[],
|
2016-03-25 00:47:46 +00:00
|
|
|
uint16_t nb_pkts, uint16_t max_pkts, void *user_param);
|
|
|
|
|
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
|
|
|
|
em_main_loop(__attribute__((unused)) void *dummy);
|
|
|
|
|
|
|
|
int
|
|
|
|
lpm_main_loop(__attribute__((unused)) void *dummy);
|
|
|
|
|
|
|
|
/* Return ipv4/ipv6 fwd lookup struct for LPM or EM. */
|
|
|
|
void *
|
|
|
|
em_get_ipv4_l3fwd_lookup_struct(const int socketid);
|
|
|
|
|
|
|
|
void *
|
|
|
|
em_get_ipv6_l3fwd_lookup_struct(const int socketid);
|
|
|
|
|
|
|
|
void *
|
|
|
|
lpm_get_ipv4_l3fwd_lookup_struct(const int socketid);
|
|
|
|
|
|
|
|
void *
|
|
|
|
lpm_get_ipv6_l3fwd_lookup_struct(const int socketid);
|
|
|
|
|
|
|
|
#endif /* __L3_FWD_H__ */
|