@@ -5,7 +5,7 @@
APP = l3fwd
# all source are stored in SRCS-y
-SRCS-y := main.c l3fwd_lpm.c l3fwd_em.c l3fwd_event.c
+SRCS-y := main.c l3fwd_lpm.c l3fwd_fib.c l3fwd_em.c l3fwd_event.c
SRCS-y += l3fwd_event_generic.c l3fwd_event_internal_port.c
# Build using pkg-config variables if possible
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
+ * Copyright(c) 2010-2021 Intel Corporation
*/
#ifndef __L3_FWD_H__
@@ -180,13 +180,16 @@ is_valid_ipv4_pkt(struct rte_ipv4_hdr *pkt, uint32_t link_len)
int
init_mem(uint16_t portid, unsigned int nb_mbuf);
-/* Function pointers for LPM or EM functionality. */
+/* Function pointers for LPM, EM or FIB functionality. */
void
setup_lpm(const int socketid);
void
setup_hash(const int socketid);
+void
+setup_fib(const int socketid);
+
int
em_check_ptype(int portid);
@@ -207,6 +210,9 @@ em_main_loop(__rte_unused void *dummy);
int
lpm_main_loop(__rte_unused void *dummy);
+int
+fib_main_loop(__rte_unused void *dummy);
+
int
lpm_event_main_loop_tx_d(__rte_unused void *dummy);
int
@@ -225,8 +231,17 @@ em_event_main_loop_tx_q(__rte_unused void *dummy);
int
em_event_main_loop_tx_q_burst(__rte_unused void *dummy);
+int
+fib_event_main_loop_tx_d(__rte_unused void *dummy);
+int
+fib_event_main_loop_tx_d_burst(__rte_unused void *dummy);
+int
+fib_event_main_loop_tx_q(__rte_unused void *dummy);
+int
+fib_event_main_loop_tx_q_burst(__rte_unused void *dummy);
+
-/* Return ipv4/ipv6 fwd lookup struct for LPM or EM. */
+/* Return ipv4/ipv6 fwd lookup struct for LPM, EM or FIB. */
void *
em_get_ipv4_l3fwd_lookup_struct(const int socketid);
@@ -239,4 +254,10 @@ lpm_get_ipv4_l3fwd_lookup_struct(const int socketid);
void *
lpm_get_ipv6_l3fwd_lookup_struct(const int socketid);
+void *
+fib_get_ipv4_l3fwd_lookup_struct(const int socketid);
+
+void *
+fib_get_ipv6_l3fwd_lookup_struct(const int socketid);
+
#endif /* __L3_FWD_H__ */
@@ -227,6 +227,12 @@ l3fwd_event_resource_setup(struct rte_eth_conf *port_conf)
[1][0] = em_event_main_loop_tx_q,
[1][1] = em_event_main_loop_tx_q_burst,
};
+ const event_loop_cb fib_event_loop[2][2] = {
+ [0][0] = fib_event_main_loop_tx_d,
+ [0][1] = fib_event_main_loop_tx_d_burst,
+ [1][0] = fib_event_main_loop_tx_q,
+ [1][1] = fib_event_main_loop_tx_q_burst,
+ };
uint32_t event_queue_cfg;
int ret;
@@ -264,4 +270,7 @@ l3fwd_event_resource_setup(struct rte_eth_conf *port_conf)
evt_rsrc->ops.em_event_loop = em_event_loop[evt_rsrc->tx_mode_q]
[evt_rsrc->has_burst];
+
+ evt_rsrc->ops.fib_event_loop = fib_event_loop[evt_rsrc->tx_mode_q]
+ [evt_rsrc->has_burst];
}
@@ -55,6 +55,7 @@ struct l3fwd_event_setup_ops {
adapter_setup_cb adapter_setup;
event_loop_cb lpm_event_loop;
event_loop_cb em_event_loop;
+ event_loop_cb fib_event_loop;
};
struct l3fwd_event_resources {
new file mode 100644
@@ -0,0 +1,60 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2021 Intel Corporation
+ */
+
+#include <rte_fib.h>
+#include <rte_fib6.h>
+
+#include "l3fwd.h"
+#include "l3fwd_event.h"
+#include "l3fwd_route.h"
+
+/* Main fib processing loop. */
+int
+fib_main_loop(__rte_unused void *dummy)
+{
+ return 0;
+}
+
+int __rte_noinline
+fib_event_main_loop_tx_d(__rte_unused void *dummy)
+{
+ return 0;
+}
+
+int __rte_noinline
+fib_event_main_loop_tx_d_burst(__rte_unused void *dummy)
+{
+ return 0;
+}
+
+int __rte_noinline
+fib_event_main_loop_tx_q(__rte_unused void *dummy)
+{
+ return 0;
+}
+
+int __rte_noinline
+fib_event_main_loop_tx_q_burst(__rte_unused void *dummy)
+{
+ return 0;
+}
+
+/* Function to setup fib. */
+void
+setup_fib(__rte_unused const int socketid)
+{}
+
+/* Return ipv4 fib lookup struct. */
+void *
+fib_get_ipv4_l3fwd_lookup_struct(__rte_unused const int socketid)
+{
+ return 0;
+}
+
+/* Return ipv6 fib lookup struct. */
+void *
+fib_get_ipv6_l3fwd_lookup_struct(__rte_unused const int socketid)
+{
+ return 0;
+}
@@ -1,5 +1,5 @@
/* SPDX-License-Identifier: BSD-3-Clause
- * Copyright(c) 2010-2016 Intel Corporation
+ * Copyright(c) 2010-2021 Intel Corporation
*/
#include <stdio.h>
@@ -61,9 +61,14 @@ static uint16_t nb_txd = RTE_TEST_TX_DESC_DEFAULT;
/**< Ports set in promiscuous mode off by default. */
static int promiscuous_on;
-/* Select Longest-Prefix or Exact match. */
-static int l3fwd_lpm_on;
-static int l3fwd_em_on;
+/* Select Longest-Prefix, Exact match or Forwarding Information Base. */
+enum L3FWD_LOOKUP_MODE {
+ L3FWD_LOOKUP_DEFAULT,
+ L3FWD_LOOKUP_LPM,
+ L3FWD_LOOKUP_EM,
+ L3FWD_LOOKUP_FIB
+};
+static enum L3FWD_LOOKUP_MODE lookup_mode;
/* Global variables. */
@@ -163,6 +168,15 @@ static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
};
+static struct l3fwd_lkp_mode l3fwd_fib_lkp = {
+ .setup = setup_fib,
+ .check_ptype = lpm_check_ptype,
+ .cb_parse_ptype = lpm_cb_parse_ptype,
+ .main_loop = fib_main_loop,
+ .get_ipv4_lookup_struct = fib_get_ipv4_l3fwd_lookup_struct,
+ .get_ipv6_lookup_struct = fib_get_ipv6_l3fwd_lookup_struct,
+};
+
/*
* 198.18.0.0/16 are set aside for RFC2544 benchmarking (RFC5735).
* 198.18.{0-7}.0/24 = Port {0-7}
@@ -195,15 +209,18 @@ const struct ipv6_l3fwd_route ipv6_l3fwd_route_array[] = {
/*
* Setup lookup methods for forwarding.
- * Currently exact-match and longest-prefix-match
- * are supported ones.
+ * Currently exact-match, longest-prefix-match and forwarding information
+ * base are the supported ones.
*/
static void
setup_l3fwd_lookup_tables(void)
{
/* Setup HASH lookup functions. */
- if (l3fwd_em_on)
+ if (lookup_mode == L3FWD_LOOKUP_EM)
l3fwd_lkp = l3fwd_em_lkp;
+ /* Setup FIB lookup functions. */
+ else if (lookup_mode == L3FWD_LOOKUP_FIB)
+ l3fwd_lkp = l3fwd_fib_lkp;
/* Setup LPM lookup functions. */
else
l3fwd_lkp = l3fwd_lpm_lkp;
@@ -306,8 +323,7 @@ print_usage(const char *prgname)
fprintf(stderr, "%s [EAL options] --"
" -p PORTMASK"
" [-P]"
- " [-E]"
- " [-L]"
+ " [--lookup]"
" --config (port,queue,lcore)[,(port,queue,lcore)]"
" [--eth-dest=X,MM:MM:MM:MM:MM:MM]"
" [--enable-jumbo [--max-pkt-len PKTLEN]]"
@@ -317,12 +333,15 @@ print_usage(const char *prgname)
" [--parse-ptype]"
" [--per-port-pool]"
" [--mode]"
- " [--eventq-sched]\n\n"
+ " [--eventq-sched]"
+ " [-E]"
+ " [-L]\n\n"
" -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"
+ " --lookup: Select the lookup method\n"
+ " Default: lpm\n"
+ " Accepted: em (Exact Match), lpm (Longest Prefix Match), fib (Forwarding Information Base)\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"
@@ -341,7 +360,9 @@ print_usage(const char *prgname)
" Valid only if --mode=eventdev\n"
" --event-eth-rxqs: Number of ethernet RX queues per device.\n"
" Default: 1\n"
- " Valid only if --mode=eventdev\n\n",
+ " Valid only if --mode=eventdev\n"
+ " -E : Enable exact match, legacy flag please use --lookup=em instead\n"
+ " -L : Enable longest prefix match, legacy flag please use --lookup=lpm instead\n\n",
prgname);
}
@@ -516,13 +537,29 @@ parse_event_eth_rx_queues(const char *eth_rx_queues)
evt_rsrc->eth_rx_queues = num_eth_rx_queues;
}
+static int
+parse_lookup(const char *optarg)
+{
+ if (!strcmp(optarg, "em"))
+ lookup_mode = L3FWD_LOOKUP_EM;
+ else if (!strcmp(optarg, "lpm"))
+ lookup_mode = L3FWD_LOOKUP_LPM;
+ else if (!strcmp(optarg, "fib"))
+ lookup_mode = L3FWD_LOOKUP_FIB;
+ else {
+ fprintf(stderr, "Invalid lookup option! Accepted options: em, lpm, fib\n");
+ return -1;
+ }
+ return 0;
+}
+
#define MAX_JUMBO_PKT_LEN 9600
static const char short_options[] =
"p:" /* portmask */
"P" /* promiscuous */
- "L" /* enable long prefix match */
- "E" /* enable exact match */
+ "L" /* legacy enable long prefix match */
+ "E" /* legacy enable exact match */
;
#define CMD_LINE_OPT_CONFIG "config"
@@ -536,6 +573,7 @@ static const char short_options[] =
#define CMD_LINE_OPT_MODE "mode"
#define CMD_LINE_OPT_EVENTQ_SYNC "eventq-sched"
#define CMD_LINE_OPT_EVENT_ETH_RX_QUEUES "event-eth-rxqs"
+#define CMD_LINE_OPT_LOOKUP "lookup"
enum {
/* long options mapped to a short option */
@@ -553,6 +591,7 @@ enum {
CMD_LINE_OPT_MODE_NUM,
CMD_LINE_OPT_EVENTQ_SYNC_NUM,
CMD_LINE_OPT_EVENT_ETH_RX_QUEUES_NUM,
+ CMD_LINE_OPT_LOOKUP_NUM,
};
static const struct option lgopts[] = {
@@ -568,6 +607,7 @@ static const struct option lgopts[] = {
{CMD_LINE_OPT_EVENTQ_SYNC, 1, 0, CMD_LINE_OPT_EVENTQ_SYNC_NUM},
{CMD_LINE_OPT_EVENT_ETH_RX_QUEUES, 1, 0,
CMD_LINE_OPT_EVENT_ETH_RX_QUEUES_NUM},
+ {CMD_LINE_OPT_LOOKUP, 1, 0, CMD_LINE_OPT_LOOKUP_NUM},
{NULL, 0, 0, 0}
};
@@ -620,11 +660,19 @@ parse_args(int argc, char **argv)
break;
case 'E':
- l3fwd_em_on = 1;
+ if (lookup_mode != L3FWD_LOOKUP_DEFAULT) {
+ fprintf(stderr, "Only one lookup mode is allowed at a time!\n");
+ return -1;
+ }
+ lookup_mode = L3FWD_LOOKUP_EM;
break;
case 'L':
- l3fwd_lpm_on = 1;
+ if (lookup_mode != L3FWD_LOOKUP_DEFAULT) {
+ fprintf(stderr, "Only one lookup mode is allowed at a time!\n");
+ return -1;
+ }
+ lookup_mode = L3FWD_LOOKUP_LPM;
break;
/* long options */
@@ -711,18 +759,27 @@ parse_args(int argc, char **argv)
eth_rx_q = 1;
break;
+ case CMD_LINE_OPT_LOOKUP_NUM:
+ if (lookup_mode != L3FWD_LOOKUP_DEFAULT) {
+ fprintf(stderr, "Only one lookup mode is allowed at a time!\n");
+ return -1;
+ }
+ ret = parse_lookup(optarg);
+ /*
+ * If parse_lookup was passed an invalid lookup type
+ * then return -1. Error log included within
+ * parse_lookup for simplicity.
+ */
+ if (ret)
+ return -1;
+ break;
+
default:
print_usage(prgname);
return -1;
}
}
- /* If both LPM and EM are selected, return error. */
- if (l3fwd_lpm_on && l3fwd_em_on) {
- fprintf(stderr, "LPM and EM are mutually exclusive, select only one\n");
- return -1;
- }
-
if (evt_rsrc->enabled && lcore_params) {
fprintf(stderr, "lcore config is not valid when event mode is selected\n");
return -1;
@@ -742,17 +799,17 @@ parse_args(int argc, char **argv)
* Nothing is selected, pick longest-prefix match
* as default match.
*/
- if (!l3fwd_lpm_on && !l3fwd_em_on) {
- fprintf(stderr, "LPM or EM none selected, default LPM on\n");
- l3fwd_lpm_on = 1;
+ if (lookup_mode == L3FWD_LOOKUP_DEFAULT) {
+ fprintf(stderr, "Neither LPM, EM, or FIB selected, defaulting to LPM\n");
+ lookup_mode = L3FWD_LOOKUP_LPM;
}
/*
* ipv6 and hash flags are valid only for
- * exact macth, reset them to default for
+ * exact match, reset them to default for
* longest-prefix match.
*/
- if (l3fwd_lpm_on) {
+ if (lookup_mode == L3FWD_LOOKUP_LPM) {
ipv6 = 0;
hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT;
}
@@ -811,7 +868,7 @@ init_mem(uint16_t portid, unsigned int nb_mbuf)
printf("Allocated mbuf pool on socket %d\n",
socketid);
- /* Setup either LPM or EM(f.e Hash). But, only once per
+ /* Setup LPM, EM(f.e Hash) or FIB. But, only once per
* available socket.
*/
if (!lkp_per_socket[socketid]) {
@@ -1250,8 +1307,10 @@ main(int argc, char **argv)
/* Configure eventdev parameters if user has requested */
if (evt_rsrc->enabled) {
l3fwd_event_resource_setup(&port_conf);
- if (l3fwd_em_on)
+ if (lookup_mode == L3FWD_LOOKUP_EM)
l3fwd_lkp.main_loop = evt_rsrc->ops.em_event_loop;
+ else if (lookup_mode == L3FWD_LOOKUP_FIB)
+ l3fwd_lkp.main_loop = evt_rsrc->ops.fib_event_loop;
else
l3fwd_lkp.main_loop = evt_rsrc->ops.lpm_event_loop;
l3fwd_event_service_setup();
@@ -7,8 +7,8 @@
# DPDK instance, use 'make'
allow_experimental_apis = true
-deps += ['hash', 'lpm', 'eventdev']
+deps += ['hash', 'lpm', 'fib', 'eventdev']
sources = files(
- 'l3fwd_em.c', 'l3fwd_lpm.c', 'l3fwd_event.c',
+ 'l3fwd_em.c', 'l3fwd_lpm.c', 'l3fwd_fib.c', 'l3fwd_event.c',
'l3fwd_event_internal_port.c', 'l3fwd_event_generic.c', 'main.c'
)