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 11:24:24 +01: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>
|
|
|
|
#include <stdbool.h>
|
2019-05-02 17:51:51 +01:00
|
|
|
#include <sys/socket.h>
|
2019-04-10 10:41:32 -07:00
|
|
|
#include <arpa/inet.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 11:24:24 +01:00
|
|
|
|
|
|
|
#include <rte_debug.h>
|
|
|
|
#include <rte_ether.h>
|
|
|
|
#include <rte_ethdev.h>
|
|
|
|
#include <rte_cycles.h>
|
|
|
|
#include <rte_mbuf.h>
|
|
|
|
#include <rte_ip.h>
|
|
|
|
#include <rte_tcp.h>
|
|
|
|
#include <rte_udp.h>
|
|
|
|
#include <rte_lpm.h>
|
|
|
|
#include <rte_lpm6.h>
|
|
|
|
|
|
|
|
#include "l3fwd.h"
|
|
|
|
|
|
|
|
struct ipv4_l3fwd_lpm_route {
|
|
|
|
uint32_t ip;
|
|
|
|
uint8_t depth;
|
|
|
|
uint8_t if_out;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ipv6_l3fwd_lpm_route {
|
|
|
|
uint8_t ip[16];
|
|
|
|
uint8_t depth;
|
|
|
|
uint8_t if_out;
|
|
|
|
};
|
|
|
|
|
2019-04-10 10:41:31 -07:00
|
|
|
/* 192.18.0.0/16 are set aside for RFC2544 benchmarking. */
|
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 11:24:24 +01:00
|
|
|
static struct ipv4_l3fwd_lpm_route ipv4_l3fwd_lpm_route_array[] = {
|
2019-04-10 10:41:31 -07:00
|
|
|
{IPv4(192, 18, 0, 0), 24, 0},
|
|
|
|
{IPv4(192, 18, 1, 0), 24, 1},
|
|
|
|
{IPv4(192, 18, 2, 0), 24, 2},
|
|
|
|
{IPv4(192, 18, 3, 0), 24, 3},
|
|
|
|
{IPv4(192, 18, 4, 0), 24, 4},
|
|
|
|
{IPv4(192, 18, 5, 0), 24, 5},
|
|
|
|
{IPv4(192, 18, 6, 0), 24, 6},
|
|
|
|
{IPv4(192, 18, 7, 0), 24, 7},
|
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 11:24:24 +01:00
|
|
|
};
|
|
|
|
|
2019-04-10 10:41:31 -07:00
|
|
|
/* 2001:0200::/48 is IANA reserved range for IPv6 benchmarking (RFC5180) */
|
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 11:24:24 +01:00
|
|
|
static struct ipv6_l3fwd_lpm_route ipv6_l3fwd_lpm_route_array[] = {
|
2019-04-10 10:41:31 -07:00
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, 48, 0},
|
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 48, 1},
|
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0}, 48, 2},
|
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0}, 48, 3},
|
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0}, 48, 4},
|
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0}, 48, 5},
|
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0}, 48, 6},
|
|
|
|
{{32, 1, 2, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0}, 48, 7},
|
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 11:24:24 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
#define IPV4_L3FWD_LPM_NUM_ROUTES \
|
|
|
|
(sizeof(ipv4_l3fwd_lpm_route_array) / sizeof(ipv4_l3fwd_lpm_route_array[0]))
|
|
|
|
#define IPV6_L3FWD_LPM_NUM_ROUTES \
|
|
|
|
(sizeof(ipv6_l3fwd_lpm_route_array) / sizeof(ipv6_l3fwd_lpm_route_array[0]))
|
|
|
|
|
|
|
|
#define IPV4_L3FWD_LPM_MAX_RULES 1024
|
2016-03-09 17:57:16 +01:00
|
|
|
#define IPV4_L3FWD_LPM_NUMBER_TBL8S (1 << 8)
|
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 11:24:24 +01:00
|
|
|
#define IPV6_L3FWD_LPM_MAX_RULES 1024
|
|
|
|
#define IPV6_L3FWD_LPM_NUMBER_TBL8S (1 << 16)
|
|
|
|
|
|
|
|
struct rte_lpm *ipv4_l3fwd_lpm_lookup_struct[NB_SOCKETS];
|
|
|
|
struct rte_lpm6 *ipv6_l3fwd_lpm_lookup_struct[NB_SOCKETS];
|
|
|
|
|
2017-07-04 18:24:01 +08:00
|
|
|
static inline uint16_t
|
2017-09-29 15:17:24 +08:00
|
|
|
lpm_get_ipv4_dst_port(void *ipv4_hdr, uint16_t portid, void *lookup_struct)
|
2017-07-04 18:24:01 +08:00
|
|
|
{
|
|
|
|
uint32_t next_hop;
|
|
|
|
struct rte_lpm *ipv4_l3fwd_lookup_struct =
|
|
|
|
(struct rte_lpm *)lookup_struct;
|
|
|
|
|
|
|
|
return (uint16_t) ((rte_lpm_lookup(ipv4_l3fwd_lookup_struct,
|
|
|
|
rte_be_to_cpu_32(((struct ipv4_hdr *)ipv4_hdr)->dst_addr),
|
|
|
|
&next_hop) == 0) ? next_hop : portid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint16_t
|
2017-09-29 15:17:24 +08:00
|
|
|
lpm_get_ipv6_dst_port(void *ipv6_hdr, uint16_t portid, void *lookup_struct)
|
2017-07-04 18:24:01 +08:00
|
|
|
{
|
|
|
|
uint32_t next_hop;
|
|
|
|
struct rte_lpm6 *ipv6_l3fwd_lookup_struct =
|
|
|
|
(struct rte_lpm6 *)lookup_struct;
|
|
|
|
|
|
|
|
return (uint16_t) ((rte_lpm6_lookup(ipv6_l3fwd_lookup_struct,
|
|
|
|
((struct ipv6_hdr *)ipv6_hdr)->dst_addr,
|
|
|
|
&next_hop) == 0) ? next_hop : portid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __rte_always_inline uint16_t
|
|
|
|
lpm_get_dst_port(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
|
2017-09-29 15:17:24 +08:00
|
|
|
uint16_t portid)
|
2017-07-04 18:24:01 +08:00
|
|
|
{
|
|
|
|
struct ipv6_hdr *ipv6_hdr;
|
|
|
|
struct ipv4_hdr *ipv4_hdr;
|
2019-05-21 18:13:03 +02:00
|
|
|
struct rte_ether_hdr *eth_hdr;
|
2017-07-04 18:24:01 +08:00
|
|
|
|
|
|
|
if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
|
|
|
|
|
2019-05-21 18:13:03 +02:00
|
|
|
eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
|
2017-07-04 18:24:01 +08:00
|
|
|
ipv4_hdr = (struct ipv4_hdr *)(eth_hdr + 1);
|
|
|
|
|
|
|
|
return lpm_get_ipv4_dst_port(ipv4_hdr, portid,
|
|
|
|
qconf->ipv4_lookup_struct);
|
|
|
|
} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
|
|
|
|
|
2019-05-21 18:13:03 +02:00
|
|
|
eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
|
2017-07-04 18:24:01 +08:00
|
|
|
ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1);
|
|
|
|
|
|
|
|
return lpm_get_ipv6_dst_port(ipv6_hdr, portid,
|
|
|
|
qconf->ipv6_lookup_struct);
|
|
|
|
}
|
|
|
|
|
|
|
|
return portid;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* lpm_get_dst_port optimized routine for packets where dst_ipv4 is already
|
|
|
|
* precalculated. If packet is ipv6 dst_addr is taken directly from packet
|
|
|
|
* header and dst_ipv4 value is not used.
|
|
|
|
*/
|
|
|
|
static __rte_always_inline uint16_t
|
|
|
|
lpm_get_dst_port_with_ipv4(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
|
2017-09-29 15:17:24 +08:00
|
|
|
uint32_t dst_ipv4, uint16_t portid)
|
2017-07-04 18:24:01 +08:00
|
|
|
{
|
|
|
|
uint32_t next_hop;
|
|
|
|
struct ipv6_hdr *ipv6_hdr;
|
2019-05-21 18:13:03 +02:00
|
|
|
struct rte_ether_hdr *eth_hdr;
|
2017-07-04 18:24:01 +08:00
|
|
|
|
|
|
|
if (RTE_ETH_IS_IPV4_HDR(pkt->packet_type)) {
|
|
|
|
return (uint16_t) ((rte_lpm_lookup(qconf->ipv4_lookup_struct,
|
|
|
|
dst_ipv4, &next_hop) == 0)
|
|
|
|
? next_hop : portid);
|
|
|
|
|
|
|
|
} else if (RTE_ETH_IS_IPV6_HDR(pkt->packet_type)) {
|
|
|
|
|
2019-05-21 18:13:03 +02:00
|
|
|
eth_hdr = rte_pktmbuf_mtod(pkt, struct rte_ether_hdr *);
|
2017-07-04 18:24:01 +08:00
|
|
|
ipv6_hdr = (struct ipv6_hdr *)(eth_hdr + 1);
|
|
|
|
|
|
|
|
return (uint16_t) ((rte_lpm6_lookup(qconf->ipv6_lookup_struct,
|
|
|
|
ipv6_hdr->dst_addr, &next_hop) == 0)
|
|
|
|
? next_hop : portid);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return portid;
|
|
|
|
}
|
|
|
|
|
2017-06-20 16:23:12 +01:00
|
|
|
#if defined(RTE_ARCH_X86)
|
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 11:24:24 +01:00
|
|
|
#include "l3fwd_lpm_sse.h"
|
2017-07-04 18:24:03 +08:00
|
|
|
#elif defined RTE_MACHINE_CPUFLAG_NEON
|
|
|
|
#include "l3fwd_lpm_neon.h"
|
2017-09-21 15:35:24 +05:30
|
|
|
#elif defined(RTE_ARCH_PPC_64)
|
|
|
|
#include "l3fwd_lpm_altivec.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 11:24:24 +01:00
|
|
|
#else
|
|
|
|
#include "l3fwd_lpm.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* main processing loop */
|
|
|
|
int
|
|
|
|
lpm_main_loop(__attribute__((unused)) void *dummy)
|
|
|
|
{
|
|
|
|
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
|
|
|
|
unsigned lcore_id;
|
|
|
|
uint64_t prev_tsc, diff_tsc, cur_tsc;
|
|
|
|
int i, nb_rx;
|
2017-09-29 15:17:24 +08:00
|
|
|
uint16_t portid;
|
|
|
|
uint8_t queueid;
|
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 11:24:24 +01:00
|
|
|
struct lcore_conf *qconf;
|
|
|
|
const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) /
|
|
|
|
US_PER_S * BURST_TX_DRAIN_US;
|
|
|
|
|
|
|
|
prev_tsc = 0;
|
|
|
|
|
|
|
|
lcore_id = rte_lcore_id();
|
|
|
|
qconf = &lcore_conf[lcore_id];
|
|
|
|
|
|
|
|
if (qconf->n_rx_queue == 0) {
|
|
|
|
RTE_LOG(INFO, L3FWD, "lcore %u has nothing to do\n", lcore_id);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
RTE_LOG(INFO, L3FWD, "entering main loop on lcore %u\n", lcore_id);
|
|
|
|
|
|
|
|
for (i = 0; i < qconf->n_rx_queue; i++) {
|
|
|
|
|
|
|
|
portid = qconf->rx_queue_list[i].port_id;
|
|
|
|
queueid = qconf->rx_queue_list[i].queue_id;
|
|
|
|
RTE_LOG(INFO, L3FWD,
|
2017-09-29 15:17:24 +08:00
|
|
|
" -- lcoreid=%u portid=%u rxqueueid=%hhu\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 11:24:24 +01:00
|
|
|
lcore_id, portid, queueid);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (!force_quit) {
|
|
|
|
|
|
|
|
cur_tsc = rte_rdtsc();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* TX burst queue drain
|
|
|
|
*/
|
|
|
|
diff_tsc = cur_tsc - prev_tsc;
|
|
|
|
if (unlikely(diff_tsc > drain_tsc)) {
|
|
|
|
|
2016-03-18 14:31:46 +01:00
|
|
|
for (i = 0; i < qconf->n_tx_port; ++i) {
|
|
|
|
portid = qconf->tx_port_id[i];
|
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 11:24:24 +01:00
|
|
|
if (qconf->tx_mbufs[portid].len == 0)
|
|
|
|
continue;
|
|
|
|
send_burst(qconf,
|
|
|
|
qconf->tx_mbufs[portid].len,
|
|
|
|
portid);
|
|
|
|
qconf->tx_mbufs[portid].len = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
prev_tsc = cur_tsc;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read packet from RX queues
|
|
|
|
*/
|
|
|
|
for (i = 0; i < qconf->n_rx_queue; ++i) {
|
|
|
|
portid = qconf->rx_queue_list[i].port_id;
|
|
|
|
queueid = qconf->rx_queue_list[i].queue_id;
|
|
|
|
nb_rx = rte_eth_rx_burst(portid, queueid, pkts_burst,
|
|
|
|
MAX_PKT_BURST);
|
|
|
|
if (nb_rx == 0)
|
|
|
|
continue;
|
|
|
|
|
2017-09-21 15:35:24 +05:30
|
|
|
#if defined RTE_ARCH_X86 || defined RTE_MACHINE_CPUFLAG_NEON \
|
|
|
|
|| defined RTE_ARCH_PPC_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 11:24:24 +01:00
|
|
|
l3fwd_lpm_send_packets(nb_rx, pkts_burst,
|
|
|
|
portid, qconf);
|
|
|
|
#else
|
|
|
|
l3fwd_lpm_no_opt_send_packets(nb_rx, pkts_burst,
|
|
|
|
portid, qconf);
|
2017-06-20 16:23:12 +01:00
|
|
|
#endif /* X86 */
|
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 11:24:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
setup_lpm(const int socketid)
|
|
|
|
{
|
|
|
|
struct rte_lpm6_config config;
|
2016-03-09 17:57:16 +01:00
|
|
|
struct rte_lpm_config config_ipv4;
|
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 11:24:24 +01:00
|
|
|
unsigned i;
|
|
|
|
int ret;
|
|
|
|
char s[64];
|
2019-04-10 10:41:32 -07:00
|
|
|
char abuf[INET6_ADDRSTRLEN];
|
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 11:24:24 +01:00
|
|
|
|
|
|
|
/* create the LPM table */
|
2016-03-09 17:57:16 +01:00
|
|
|
config_ipv4.max_rules = IPV4_L3FWD_LPM_MAX_RULES;
|
|
|
|
config_ipv4.number_tbl8s = IPV4_L3FWD_LPM_NUMBER_TBL8S;
|
|
|
|
config_ipv4.flags = 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 11:24:24 +01:00
|
|
|
snprintf(s, sizeof(s), "IPV4_L3FWD_LPM_%d", socketid);
|
2016-03-09 17:57:16 +01:00
|
|
|
ipv4_l3fwd_lpm_lookup_struct[socketid] =
|
|
|
|
rte_lpm_create(s, socketid, &config_ipv4);
|
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 11:24:24 +01:00
|
|
|
if (ipv4_l3fwd_lpm_lookup_struct[socketid] == NULL)
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Unable to create the l3fwd LPM table on socket %d\n",
|
|
|
|
socketid);
|
|
|
|
|
|
|
|
/* populate the LPM table */
|
|
|
|
for (i = 0; i < IPV4_L3FWD_LPM_NUM_ROUTES; i++) {
|
2019-04-10 10:41:32 -07:00
|
|
|
struct in_addr in;
|
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 11:24:24 +01:00
|
|
|
|
|
|
|
/* skip unused ports */
|
|
|
|
if ((1 << ipv4_l3fwd_lpm_route_array[i].if_out &
|
|
|
|
enabled_port_mask) == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ret = rte_lpm_add(ipv4_l3fwd_lpm_lookup_struct[socketid],
|
|
|
|
ipv4_l3fwd_lpm_route_array[i].ip,
|
|
|
|
ipv4_l3fwd_lpm_route_array[i].depth,
|
|
|
|
ipv4_l3fwd_lpm_route_array[i].if_out);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Unable to add entry %u to the l3fwd LPM table on socket %d\n",
|
|
|
|
i, socketid);
|
|
|
|
}
|
|
|
|
|
2019-04-10 10:41:32 -07:00
|
|
|
in.s_addr = htonl(ipv4_l3fwd_lpm_route_array[i].ip);
|
|
|
|
printf("LPM: Adding route %s / %d (%d)\n",
|
|
|
|
inet_ntop(AF_INET, &in, abuf, sizeof(abuf)),
|
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 11:24:24 +01:00
|
|
|
ipv4_l3fwd_lpm_route_array[i].depth,
|
|
|
|
ipv4_l3fwd_lpm_route_array[i].if_out);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* create the LPM6 table */
|
|
|
|
snprintf(s, sizeof(s), "IPV6_L3FWD_LPM_%d", socketid);
|
|
|
|
|
|
|
|
config.max_rules = IPV6_L3FWD_LPM_MAX_RULES;
|
|
|
|
config.number_tbl8s = IPV6_L3FWD_LPM_NUMBER_TBL8S;
|
|
|
|
config.flags = 0;
|
|
|
|
ipv6_l3fwd_lpm_lookup_struct[socketid] = rte_lpm6_create(s, socketid,
|
|
|
|
&config);
|
|
|
|
if (ipv6_l3fwd_lpm_lookup_struct[socketid] == NULL)
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Unable to create the l3fwd LPM table on socket %d\n",
|
|
|
|
socketid);
|
|
|
|
|
|
|
|
/* populate the LPM table */
|
|
|
|
for (i = 0; i < IPV6_L3FWD_LPM_NUM_ROUTES; i++) {
|
|
|
|
|
|
|
|
/* skip unused ports */
|
|
|
|
if ((1 << ipv6_l3fwd_lpm_route_array[i].if_out &
|
|
|
|
enabled_port_mask) == 0)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
ret = rte_lpm6_add(ipv6_l3fwd_lpm_lookup_struct[socketid],
|
|
|
|
ipv6_l3fwd_lpm_route_array[i].ip,
|
|
|
|
ipv6_l3fwd_lpm_route_array[i].depth,
|
|
|
|
ipv6_l3fwd_lpm_route_array[i].if_out);
|
|
|
|
|
|
|
|
if (ret < 0) {
|
|
|
|
rte_exit(EXIT_FAILURE,
|
|
|
|
"Unable to add entry %u to the l3fwd LPM table on socket %d\n",
|
|
|
|
i, socketid);
|
|
|
|
}
|
|
|
|
|
|
|
|
printf("LPM: Adding route %s / %d (%d)\n",
|
2019-04-10 10:41:32 -07:00
|
|
|
inet_ntop(AF_INET6, ipv6_l3fwd_lpm_route_array[i].ip,
|
|
|
|
abuf, sizeof(abuf)),
|
|
|
|
ipv6_l3fwd_lpm_route_array[i].depth,
|
|
|
|
ipv6_l3fwd_lpm_route_array[i].if_out);
|
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 11:24:24 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-25 08:47:46 +08:00
|
|
|
int
|
|
|
|
lpm_check_ptype(int portid)
|
|
|
|
{
|
|
|
|
int i, ret;
|
|
|
|
int ptype_l3_ipv4 = 0, ptype_l3_ipv6 = 0;
|
|
|
|
uint32_t ptype_mask = RTE_PTYPE_L3_MASK;
|
|
|
|
|
|
|
|
ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, NULL, 0);
|
|
|
|
if (ret <= 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
uint32_t ptypes[ret];
|
|
|
|
|
|
|
|
ret = rte_eth_dev_get_supported_ptypes(portid, ptype_mask, ptypes, ret);
|
|
|
|
for (i = 0; i < ret; ++i) {
|
|
|
|
if (ptypes[i] & RTE_PTYPE_L3_IPV4)
|
|
|
|
ptype_l3_ipv4 = 1;
|
|
|
|
if (ptypes[i] & RTE_PTYPE_L3_IPV6)
|
|
|
|
ptype_l3_ipv6 = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ptype_l3_ipv4 == 0)
|
|
|
|
printf("port %d cannot parse RTE_PTYPE_L3_IPV4\n", portid);
|
|
|
|
|
|
|
|
if (ptype_l3_ipv6 == 0)
|
|
|
|
printf("port %d cannot parse RTE_PTYPE_L3_IPV6\n", portid);
|
|
|
|
|
|
|
|
if (ptype_l3_ipv4 && ptype_l3_ipv6)
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline void
|
|
|
|
lpm_parse_ptype(struct rte_mbuf *m)
|
|
|
|
{
|
2019-05-21 18:13:03 +02:00
|
|
|
struct rte_ether_hdr *eth_hdr;
|
2016-03-25 08:47:46 +08:00
|
|
|
uint32_t packet_type = RTE_PTYPE_UNKNOWN;
|
|
|
|
uint16_t ether_type;
|
|
|
|
|
2019-05-21 18:13:03 +02:00
|
|
|
eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *);
|
2016-03-25 08:47:46 +08:00
|
|
|
ether_type = eth_hdr->ether_type;
|
2019-05-21 18:13:05 +02:00
|
|
|
if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv4))
|
2016-03-25 08:47:46 +08:00
|
|
|
packet_type |= RTE_PTYPE_L3_IPV4_EXT_UNKNOWN;
|
2019-05-21 18:13:05 +02:00
|
|
|
else if (ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_IPv6))
|
2016-03-25 08:47:46 +08:00
|
|
|
packet_type |= RTE_PTYPE_L3_IPV6_EXT_UNKNOWN;
|
|
|
|
|
|
|
|
m->packet_type = packet_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16_t
|
2017-09-29 15:17:24 +08:00
|
|
|
lpm_cb_parse_ptype(uint16_t port __rte_unused, uint16_t queue __rte_unused,
|
2016-03-25 08:47:46 +08:00
|
|
|
struct rte_mbuf *pkts[], uint16_t nb_pkts,
|
|
|
|
uint16_t max_pkts __rte_unused,
|
|
|
|
void *user_param __rte_unused)
|
|
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
for (i = 0; i < nb_pkts; ++i)
|
|
|
|
lpm_parse_ptype(pkts[i]);
|
|
|
|
|
|
|
|
return nb_pkts;
|
|
|
|
}
|
|
|
|
|
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 11:24:24 +01:00
|
|
|
/* Return ipv4/ipv6 lpm fwd lookup struct. */
|
|
|
|
void *
|
|
|
|
lpm_get_ipv4_l3fwd_lookup_struct(const int socketid)
|
|
|
|
{
|
|
|
|
return ipv4_l3fwd_lpm_lookup_struct[socketid];
|
|
|
|
}
|
|
|
|
|
|
|
|
void *
|
|
|
|
lpm_get_ipv6_l3fwd_lookup_struct(const int socketid)
|
|
|
|
{
|
|
|
|
return ipv6_l3fwd_lpm_lookup_struct[socketid];
|
|
|
|
}
|