From: Sean Morrissey <sean.morrissey@intel.com>
Cc: dev@dpdk.org, Sean Morrissey <sean.morrissey@intel.com>,
Konstantin Ananyev <konstantin.ananyev@intel.com>
Subject: [PATCH v5 1/2] examples/l3fwd: add config file support for LPM/FIB
Date: Fri, 4 Feb 2022 19:59:04 +0000 [thread overview]
Message-ID: <20220204195905.449192-2-sean.morrissey@intel.com> (raw)
In-Reply-To: <20220204195905.449192-1-sean.morrissey@intel.com>
Add support to define ipv4 and ipv6 forwarding tables
from reading from a config file for LPM and FIB,
with format similar to l3fwd-acl one.
Users can now use the default hardcoded route tables
or optionally config files. Default config files have
been provided for use with LPM and FIB.
Signed-off-by: Sean Morrissey <sean.morrissey@intel.com>
Acked-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
examples/l3fwd/l3fwd.h | 41 ++++
examples/l3fwd/l3fwd_em.c | 13 ++
examples/l3fwd/l3fwd_fib.c | 50 ++---
examples/l3fwd/l3fwd_lpm.c | 315 ++++++++++++++++++++++++++++--
examples/l3fwd/l3fwd_route.h | 17 ++
examples/l3fwd/lpm_default_v4.cfg | 17 ++
examples/l3fwd/lpm_default_v6.cfg | 17 ++
examples/l3fwd/main.c | 68 ++++++-
8 files changed, 495 insertions(+), 43 deletions(-)
create mode 100644 examples/l3fwd/lpm_default_v4.cfg
create mode 100644 examples/l3fwd/lpm_default_v6.cfg
diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index 38ca19133c..4e1e0af033 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -58,6 +58,30 @@
#endif
#define HASH_ENTRY_NUMBER_DEFAULT 16
+/*Log file related character defs. */
+#define COMMENT_LEAD_CHAR ('#')
+#define ROUTE_LEAD_CHAR ('R')
+
+#define IPV6_ADDR_LEN 16
+#define IPV6_ADDR_U16 (IPV6_ADDR_LEN / sizeof(uint16_t))
+#define IPV6_ADDR_U32 (IPV6_ADDR_LEN / sizeof(uint32_t))
+
+#define GET_CB_FIELD(in, fd, base, lim, dlm) do { \
+ unsigned long val; \
+ char *end; \
+ errno = 0; \
+ val = strtoul((in), &end, (base)); \
+ if (errno != 0 || end[0] != (dlm) || val > (lim)) \
+ return -EINVAL; \
+ (fd) = (typeof(fd))val; \
+ (in) = end + 1; \
+} while (0)
+
+struct parm_cfg {
+ const char *rule_ipv4_name;
+ const char *rule_ipv6_name;
+};
+
struct mbuf_table {
uint16_t len;
struct rte_mbuf *m_table[MAX_PKT_BURST];
@@ -96,6 +120,8 @@ extern xmm_t val_eth[RTE_MAX_ETHPORTS];
extern struct lcore_conf lcore_conf[RTE_MAX_LCORE];
+extern struct parm_cfg parm_config;
+
/* Send burst of packets on an output interface */
static inline int
send_burst(struct lcore_conf *qconf, uint16_t n, uint16_t port)
@@ -183,6 +209,12 @@ int
init_mem(uint16_t portid, unsigned int nb_mbuf);
/* Function pointers for LPM, EM or FIB functionality. */
+void
+read_config_files_lpm(void);
+
+void
+read_config_files_em(void);
+
void
setup_lpm(const int socketid);
@@ -286,4 +318,13 @@ fib_get_ipv4_l3fwd_lookup_struct(const int socketid);
void *
fib_get_ipv6_l3fwd_lookup_struct(const int socketid);
+void
+em_free_routes(void);
+
+void
+lpm_free_routes(void);
+
+int
+is_bypass_line(const char *buff);
+
#endif /* __L3_FWD_H__ */
diff --git a/examples/l3fwd/l3fwd_em.c b/examples/l3fwd/l3fwd_em.c
index 5cc4a4d979..9058e75a76 100644
--- a/examples/l3fwd/l3fwd_em.c
+++ b/examples/l3fwd/l3fwd_em.c
@@ -972,6 +972,19 @@ em_event_main_loop_tx_q_burst_vector(__rte_unused void *dummy)
return 0;
}
+/* Load rules from the input file */
+void
+read_config_files_em(void)
+{
+ /* Empty till config file support added to EM */
+}
+
+void
+em_free_routes(void)
+{
+ /* Empty till config file support added to EM */
+}
+
/* Initialize exact match (hash) parameters. 8< */
void
setup_hash(const int socketid)
diff --git a/examples/l3fwd/l3fwd_fib.c b/examples/l3fwd/l3fwd_fib.c
index 2110459cc3..6e0054b4cb 100644
--- a/examples/l3fwd/l3fwd_fib.c
+++ b/examples/l3fwd/l3fwd_fib.c
@@ -583,7 +583,7 @@ setup_fib(const int socketid)
struct rte_eth_dev_info dev_info;
struct rte_fib6_conf config;
struct rte_fib_conf config_ipv4;
- unsigned int i;
+ int i;
int ret;
char s[64];
char abuf[INET6_ADDRSTRLEN];
@@ -603,37 +603,39 @@ setup_fib(const int socketid)
"Unable to create the l3fwd FIB table on socket %d\n",
socketid);
+
/* Populate the fib ipv4 table. */
- for (i = 0; i < RTE_DIM(ipv4_l3fwd_route_array); i++) {
+ for (i = 0; i < route_num_v4; i++) {
struct in_addr in;
/* Skip unused ports. */
- if ((1 << ipv4_l3fwd_route_array[i].if_out &
+ if ((1 << route_base_v4[i].if_out &
enabled_port_mask) == 0)
continue;
- rte_eth_dev_info_get(ipv4_l3fwd_route_array[i].if_out,
+ rte_eth_dev_info_get(route_base_v4[i].if_out,
&dev_info);
ret = rte_fib_add(ipv4_l3fwd_fib_lookup_struct[socketid],
- ipv4_l3fwd_route_array[i].ip,
- ipv4_l3fwd_route_array[i].depth,
- ipv4_l3fwd_route_array[i].if_out);
+ route_base_v4[i].ip,
+ route_base_v4[i].depth,
+ route_base_v4[i].if_out);
if (ret < 0) {
+ free(route_base_v4);
rte_exit(EXIT_FAILURE,
"Unable to add entry %u to the l3fwd FIB table on socket %d\n",
i, socketid);
}
- in.s_addr = htonl(ipv4_l3fwd_route_array[i].ip);
+ in.s_addr = htonl(route_base_v4[i].ip);
if (inet_ntop(AF_INET, &in, abuf, sizeof(abuf)) != NULL) {
printf("FIB: Adding route %s / %d (%d) [%s]\n", abuf,
- ipv4_l3fwd_route_array[i].depth,
- ipv4_l3fwd_route_array[i].if_out,
+ route_base_v4[i].depth,
+ route_base_v4[i].if_out,
dev_info.device->name);
} else {
printf("FIB: IPv4 route added to port %d [%s]\n",
- ipv4_l3fwd_route_array[i].if_out,
+ route_base_v4[i].if_out,
dev_info.device->name);
}
}
@@ -650,41 +652,45 @@ setup_fib(const int socketid)
config.trie.num_tbl8 = (1 << 15);
ipv6_l3fwd_fib_lookup_struct[socketid] = rte_fib6_create(s, socketid,
&config);
- if (ipv6_l3fwd_fib_lookup_struct[socketid] == NULL)
+ if (ipv6_l3fwd_fib_lookup_struct[socketid] == NULL) {
+ free(route_base_v4);
rte_exit(EXIT_FAILURE,
"Unable to create the l3fwd FIB table on socket %d\n",
socketid);
+ }
/* Populate the fib IPv6 table. */
- for (i = 0; i < RTE_DIM(ipv6_l3fwd_route_array); i++) {
+ for (i = 0; i < route_num_v6; i++) {
/* Skip unused ports. */
- if ((1 << ipv6_l3fwd_route_array[i].if_out &
+ if ((1 << route_base_v6[i].if_out &
enabled_port_mask) == 0)
continue;
- rte_eth_dev_info_get(ipv6_l3fwd_route_array[i].if_out,
+ rte_eth_dev_info_get(route_base_v6[i].if_out,
&dev_info);
ret = rte_fib6_add(ipv6_l3fwd_fib_lookup_struct[socketid],
- ipv6_l3fwd_route_array[i].ip,
- ipv6_l3fwd_route_array[i].depth,
- ipv6_l3fwd_route_array[i].if_out);
+ route_base_v6[i].ip_8,
+ route_base_v6[i].depth,
+ route_base_v6[i].if_out);
if (ret < 0) {
+ free(route_base_v4);
+ free(route_base_v6);
rte_exit(EXIT_FAILURE,
"Unable to add entry %u to the l3fwd FIB table on socket %d\n",
i, socketid);
}
- if (inet_ntop(AF_INET6, ipv6_l3fwd_route_array[i].ip,
+ if (inet_ntop(AF_INET6, route_base_v6[i].ip_8,
abuf, sizeof(abuf)) != NULL) {
printf("FIB: Adding route %s / %d (%d) [%s]\n", abuf,
- ipv6_l3fwd_route_array[i].depth,
- ipv6_l3fwd_route_array[i].if_out,
+ route_base_v6[i].depth,
+ route_base_v6[i].if_out,
dev_info.device->name);
} else {
printf("FIB: IPv6 route added to port %d [%s]\n",
- ipv6_l3fwd_route_array[i].if_out,
+ route_base_v6[i].if_out,
dev_info.device->name);
}
}
diff --git a/examples/l3fwd/l3fwd_lpm.c b/examples/l3fwd/l3fwd_lpm.c
index a5b476ced3..9e24ad1e7e 100644
--- a/examples/l3fwd/l3fwd_lpm.c
+++ b/examples/l3fwd/l3fwd_lpm.c
@@ -39,6 +39,16 @@
static struct rte_lpm *ipv4_l3fwd_lpm_lookup_struct[NB_SOCKETS];
static struct rte_lpm6 *ipv6_l3fwd_lpm_lookup_struct[NB_SOCKETS];
+struct lpm_route_rule *route_base_v4;
+struct lpm_route_rule *route_base_v6;
+int route_num_v4;
+int route_num_v6;
+
+enum {
+ CB_FLD_DST_ADDR,
+ CB_FLD_IF_OUT,
+ CB_FLD_MAX
+};
/* Performing LPM-based lookups. 8< */
static inline uint16_t
@@ -139,6 +149,233 @@ lpm_get_dst_port_with_ipv4(const struct lcore_conf *qconf, struct rte_mbuf *pkt,
#include "l3fwd_lpm.h"
#endif
+static int
+parse_ipv6_addr_mask(char *token, uint32_t *ipv6, uint8_t *mask)
+{
+ char *sa, *sm, *sv;
+ const char *dlm = "/";
+
+ sv = NULL;
+ sa = strtok_r(token, dlm, &sv);
+ if (sa == NULL)
+ return -EINVAL;
+ sm = strtok_r(NULL, dlm, &sv);
+ if (sm == NULL)
+ return -EINVAL;
+
+ if (inet_pton(AF_INET6, sa, ipv6) != 1)
+ return -EINVAL;
+
+ GET_CB_FIELD(sm, *mask, 0, 128, 0);
+ return 0;
+}
+
+static int
+parse_ipv4_addr_mask(char *token, uint32_t *ipv4, uint8_t *mask)
+{
+ char *sa, *sm, *sv;
+ const char *dlm = "/";
+
+ sv = NULL;
+ sa = strtok_r(token, dlm, &sv);
+ if (sa == NULL)
+ return -EINVAL;
+ sm = strtok_r(NULL, dlm, &sv);
+ if (sm == NULL)
+ return -EINVAL;
+
+ if (inet_pton(AF_INET, sa, ipv4) != 1)
+ return -EINVAL;
+
+ GET_CB_FIELD(sm, *mask, 0, 32, 0);
+ *ipv4 = ntohl(*ipv4);
+ return 0;
+}
+
+static int
+lpm_parse_v6_net(char *in, uint32_t *v, uint8_t *mask_len)
+{
+ int32_t rc;
+
+ /* get address. */
+ rc = parse_ipv6_addr_mask(in, v, mask_len);
+
+ return rc;
+}
+
+static int
+lpm_parse_v6_rule(char *str, struct lpm_route_rule *v)
+{
+ int i, rc;
+ char *s, *sp, *in[CB_FLD_MAX];
+ static const char *dlm = " \t\n";
+ int dim = CB_FLD_MAX;
+ s = str;
+
+ for (i = 0; i != dim; i++, s = NULL) {
+ in[i] = strtok_r(s, dlm, &sp);
+ if (in[i] == NULL)
+ return -EINVAL;
+ }
+
+ rc = lpm_parse_v6_net(in[CB_FLD_DST_ADDR], v->ip_32, &v->depth);
+
+ GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);
+
+ return rc;
+}
+
+static int
+lpm_parse_v4_rule(char *str, struct lpm_route_rule *v)
+{
+ int i, rc;
+ char *s, *sp, *in[CB_FLD_MAX];
+ static const char *dlm = " \t\n";
+ int dim = CB_FLD_MAX;
+ s = str;
+
+ for (i = 0; i != dim; i++, s = NULL) {
+ in[i] = strtok_r(s, dlm, &sp);
+ if (in[i] == NULL)
+ return -EINVAL;
+ }
+
+ rc = parse_ipv4_addr_mask(in[CB_FLD_DST_ADDR], &v->ip, &v->depth);
+
+ GET_CB_FIELD(in[CB_FLD_IF_OUT], v->if_out, 0, UINT8_MAX, 0);
+
+ return rc;
+}
+
+static int
+lpm_add_rules(const char *rule_path,
+ struct lpm_route_rule **proute_base,
+ int (*parser)(char *, struct lpm_route_rule *))
+{
+ struct lpm_route_rule *route_rules;
+ struct lpm_route_rule *next;
+ unsigned int route_num = 0;
+ unsigned int route_cnt = 0;
+ char buff[LINE_MAX];
+ FILE *fh;
+ unsigned int i = 0, rule_size = sizeof(*next);
+ int val;
+
+ *proute_base = NULL;
+ fh = fopen(rule_path, "rb");
+ if (fh == NULL)
+ return -EINVAL;
+
+ while ((fgets(buff, LINE_MAX, fh) != NULL)) {
+ if (buff[0] == ROUTE_LEAD_CHAR)
+ route_num++;
+ }
+
+ if (route_num == 0) {
+ fclose(fh);
+ return -EINVAL;
+ }
+
+ val = fseek(fh, 0, SEEK_SET);
+ if (val < 0) {
+ fclose(fh);
+ return -EINVAL;
+ }
+
+ route_rules = calloc(route_num, rule_size);
+
+ if (route_rules == NULL) {
+ fclose(fh);
+ return -EINVAL;
+ }
+
+ i = 0;
+ while (fgets(buff, LINE_MAX, fh) != NULL) {
+ i++;
+ if (is_bypass_line(buff))
+ continue;
+
+ char s = buff[0];
+
+ /* Route entry */
+ if (s == ROUTE_LEAD_CHAR)
+ next = &route_rules[route_cnt];
+
+ /* Illegal line */
+ else {
+ RTE_LOG(ERR, L3FWD,
+ "%s Line %u: should start with leading "
+ "char %c\n",
+ rule_path, i, ROUTE_LEAD_CHAR);
+ fclose(fh);
+ free(route_rules);
+ return -EINVAL;
+ }
+
+ if (parser(buff + 1, next) != 0) {
+ RTE_LOG(ERR, L3FWD,
+ "%s Line %u: parse rules error\n",
+ rule_path, i);
+ fclose(fh);
+ free(route_rules);
+ return -EINVAL;
+ }
+
+ route_cnt++;
+ }
+
+ fclose(fh);
+
+ *proute_base = route_rules;
+
+ return route_cnt;
+}
+
+static int
+lpm_add_default_v4_rules(void)
+{
+ /* populate the LPM IPv4 table */
+ unsigned int i, rule_size = sizeof(*route_base_v4);
+ route_num_v4 = RTE_DIM(ipv4_l3fwd_route_array);
+
+ route_base_v4 = calloc(route_num_v4, rule_size);
+
+ for (i = 0; i < (unsigned int)route_num_v4; i++) {
+ route_base_v4[i].ip = ipv4_l3fwd_route_array[i].ip;
+ route_base_v4[i].depth = ipv4_l3fwd_route_array[i].depth;
+ route_base_v4[i].if_out = ipv4_l3fwd_route_array[i].if_out;
+ }
+ return 0;
+}
+
+static int
+lpm_add_default_v6_rules(void)
+{
+ /* populate the LPM IPv6 table */
+ unsigned int i, rule_size = sizeof(*route_base_v6);
+ route_num_v6 = RTE_DIM(ipv6_l3fwd_route_array);
+
+ route_base_v6 = calloc(route_num_v6, rule_size);
+
+ for (i = 0; i < (unsigned int)route_num_v6; i++) {
+ *(route_base_v6[i].ip_8) = *(ipv6_l3fwd_route_array[i].ip);
+ route_base_v6[i].depth = ipv6_l3fwd_route_array[i].depth;
+ route_base_v6[i].if_out = ipv6_l3fwd_route_array[i].if_out;
+ }
+ return 0;
+}
+
+void
+lpm_free_routes(void)
+{
+ free(route_base_v4);
+ free(route_base_v6);
+ route_base_v4 = NULL;
+ route_base_v6 = NULL;
+ route_num_v4 = 0;
+ route_num_v6 = 0;
+}
+
/* main processing loop */
int
lpm_main_loop(__rte_unused void *dummy)
@@ -548,13 +785,47 @@ lpm_event_main_loop_tx_q_burst_vector(__rte_unused void *dummy)
return 0;
}
+/* Load rules from the input file */
+void
+read_config_files_lpm(void)
+{
+ if (parm_config.rule_ipv4_name != NULL &&
+ parm_config.rule_ipv6_name != NULL) {
+ /* ipv4 check */
+ route_num_v4 = lpm_add_rules(parm_config.rule_ipv4_name,
+ &route_base_v4, &lpm_parse_v4_rule);
+ if (route_num_v4 < 0) {
+ lpm_free_routes();
+ rte_exit(EXIT_FAILURE, "Failed to add IPv4 rules\n");
+ }
+
+ /* ipv6 check */
+ route_num_v6 = lpm_add_rules(parm_config.rule_ipv6_name,
+ &route_base_v6, &lpm_parse_v6_rule);
+ if (route_num_v6 < 0) {
+ lpm_free_routes();
+ rte_exit(EXIT_FAILURE, "Failed to add IPv6 rules\n");
+ }
+ } else {
+ RTE_LOG(INFO, L3FWD, "Missing 1 or more rule files, using default instead\n");
+ if (lpm_add_default_v4_rules() < 0) {
+ lpm_free_routes();
+ rte_exit(EXIT_FAILURE, "Failed to add default IPv4 rules\n");
+ }
+ if (lpm_add_default_v6_rules() < 0) {
+ lpm_free_routes();
+ rte_exit(EXIT_FAILURE, "Failed to add default IPv6 rules\n");
+ }
+ }
+}
+
void
setup_lpm(const int socketid)
{
struct rte_eth_dev_info dev_info;
struct rte_lpm6_config config;
struct rte_lpm_config config_ipv4;
- unsigned i;
+ int i;
int ret;
char s[64];
char abuf[INET6_ADDRSTRLEN];
@@ -572,32 +843,33 @@ setup_lpm(const int socketid)
socketid);
/* populate the LPM table */
- for (i = 0; i < RTE_DIM(ipv4_l3fwd_route_array); i++) {
+ for (i = 0; i < route_num_v4; i++) {
struct in_addr in;
/* skip unused ports */
- if ((1 << ipv4_l3fwd_route_array[i].if_out &
+ if ((1 << route_base_v4[i].if_out &
enabled_port_mask) == 0)
continue;
- rte_eth_dev_info_get(ipv4_l3fwd_route_array[i].if_out,
+ rte_eth_dev_info_get(route_base_v4[i].if_out,
&dev_info);
ret = rte_lpm_add(ipv4_l3fwd_lpm_lookup_struct[socketid],
- ipv4_l3fwd_route_array[i].ip,
- ipv4_l3fwd_route_array[i].depth,
- ipv4_l3fwd_route_array[i].if_out);
+ route_base_v4[i].ip,
+ route_base_v4[i].depth,
+ route_base_v4[i].if_out);
if (ret < 0) {
+ lpm_free_routes();
rte_exit(EXIT_FAILURE,
"Unable to add entry %u to the l3fwd LPM table on socket %d\n",
i, socketid);
}
- in.s_addr = htonl(ipv4_l3fwd_route_array[i].ip);
+ in.s_addr = htonl(route_base_v4[i].ip);
printf("LPM: Adding route %s / %d (%d) [%s]\n",
inet_ntop(AF_INET, &in, abuf, sizeof(abuf)),
- ipv4_l3fwd_route_array[i].depth,
- ipv4_l3fwd_route_array[i].if_out, dev_info.device->name);
+ route_base_v4[i].depth,
+ route_base_v4[i].if_out, dev_info.device->name);
}
/* create the LPM6 table */
@@ -608,37 +880,40 @@ setup_lpm(const int socketid)
config.flags = 0;
ipv6_l3fwd_lpm_lookup_struct[socketid] = rte_lpm6_create(s, socketid,
&config);
- if (ipv6_l3fwd_lpm_lookup_struct[socketid] == NULL)
+ if (ipv6_l3fwd_lpm_lookup_struct[socketid] == NULL) {
+ lpm_free_routes();
rte_exit(EXIT_FAILURE,
"Unable to create the l3fwd LPM table on socket %d\n",
socketid);
+ }
/* populate the LPM table */
- for (i = 0; i < RTE_DIM(ipv6_l3fwd_route_array); i++) {
+ for (i = 0; i < route_num_v6; i++) {
/* skip unused ports */
- if ((1 << ipv6_l3fwd_route_array[i].if_out &
+ if ((1 << route_base_v6[i].if_out &
enabled_port_mask) == 0)
continue;
- rte_eth_dev_info_get(ipv4_l3fwd_route_array[i].if_out,
+ rte_eth_dev_info_get(route_base_v6[i].if_out,
&dev_info);
ret = rte_lpm6_add(ipv6_l3fwd_lpm_lookup_struct[socketid],
- ipv6_l3fwd_route_array[i].ip,
- ipv6_l3fwd_route_array[i].depth,
- ipv6_l3fwd_route_array[i].if_out);
+ route_base_v6[i].ip_8,
+ route_base_v6[i].depth,
+ route_base_v6[i].if_out);
if (ret < 0) {
+ lpm_free_routes();
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) [%s]\n",
- inet_ntop(AF_INET6, ipv6_l3fwd_route_array[i].ip, abuf,
+ inet_ntop(AF_INET6, route_base_v6[i].ip_8, abuf,
sizeof(abuf)),
- ipv6_l3fwd_route_array[i].depth,
- ipv6_l3fwd_route_array[i].if_out, dev_info.device->name);
+ route_base_v6[i].depth,
+ route_base_v6[i].if_out, dev_info.device->name);
}
}
diff --git a/examples/l3fwd/l3fwd_route.h b/examples/l3fwd/l3fwd_route.h
index c7eba06c4d..843ffbe9fa 100644
--- a/examples/l3fwd/l3fwd_route.h
+++ b/examples/l3fwd/l3fwd_route.h
@@ -14,6 +14,23 @@ struct ipv6_l3fwd_route {
uint8_t if_out;
};
+struct lpm_route_rule {
+ union {
+ uint32_t ip;
+ union {
+ uint32_t ip_32[IPV6_ADDR_U32];
+ uint8_t ip_8[IPV6_ADDR_LEN];
+ };
+ };
+ uint8_t depth;
+ uint8_t if_out;
+};
+
+extern struct lpm_route_rule *route_base_v4;
+extern struct lpm_route_rule *route_base_v6;
+extern int route_num_v4;
+extern int route_num_v6;
+
extern const struct ipv4_l3fwd_route ipv4_l3fwd_route_array[16];
extern const struct ipv6_l3fwd_route ipv6_l3fwd_route_array[16];
diff --git a/examples/l3fwd/lpm_default_v4.cfg b/examples/l3fwd/lpm_default_v4.cfg
new file mode 100644
index 0000000000..4db5597ed8
--- /dev/null
+++ b/examples/l3fwd/lpm_default_v4.cfg
@@ -0,0 +1,17 @@
+#Copy of hard-coded IPv4 FWD table for L3FWD LPM
+R198.18.0.0/24 0
+R198.18.1.0/24 1
+R198.18.2.0/24 2
+R198.18.3.0/24 3
+R198.18.4.0/24 4
+R198.18.5.0/24 5
+R198.18.6.0/24 6
+R198.18.7.0/24 7
+R198.18.8.0/24 8
+R198.18.9.0/24 9
+R198.18.10.0/24 10
+R198.18.11.0/24 11
+R198.18.12.0/24 12
+R198.18.13.0/24 13
+R198.18.14.0/24 14
+R198.18.15.0/24 15
diff --git a/examples/l3fwd/lpm_default_v6.cfg b/examples/l3fwd/lpm_default_v6.cfg
new file mode 100644
index 0000000000..c50233e0ba
--- /dev/null
+++ b/examples/l3fwd/lpm_default_v6.cfg
@@ -0,0 +1,17 @@
+#Copy of hard-coded IPv6 FWD table for L3FWD LPM
+R2001:0200:0000:0000:0000:0000:0000:0000/64 0
+R2001:0200:0000:0001:0000:0000:0000:0000/64 1
+R2001:0200:0000:0002:0000:0000:0000:0000/64 2
+R2001:0200:0000:0003:0000:0000:0000:0000/64 3
+R2001:0200:0000:0004:0000:0000:0000:0000/64 4
+R2001:0200:0000:0005:0000:0000:0000:0000/64 5
+R2001:0200:0000:0006:0000:0000:0000:0000/64 6
+R2001:0200:0000:0007:0000:0000:0000:0000/64 7
+R2001:0200:0000:0008:0000:0000:0000:0000/64 8
+R2001:0200:0000:0009:0000:0000:0000:0000/64 9
+R2001:0200:0000:000A:0000:0000:0000:0000/64 10
+R2001:0200:0000:000B:0000:0000:0000:0000/64 11
+R2001:0200:0000:000C:0000:0000:0000:0000/64 12
+R2001:0200:0000:000D:0000:0000:0000:0000/64 13
+R2001:0200:0000:000E:0000:0000:0000:0000/64 14
+R2001:0200:0000:000F:0000:0000:0000:0000/64 15
diff --git a/examples/l3fwd/main.c b/examples/l3fwd/main.c
index eb68ffc5aa..8383d8f095 100644
--- a/examples/l3fwd/main.c
+++ b/examples/l3fwd/main.c
@@ -94,6 +94,8 @@ uint32_t hash_entry_number = HASH_ENTRY_NUMBER_DEFAULT;
struct lcore_conf lcore_conf[RTE_MAX_LCORE];
+struct parm_cfg parm_config;
+
struct lcore_params {
uint16_t port_id;
uint8_t queue_id;
@@ -141,41 +143,49 @@ static struct rte_mempool *vector_pool[RTE_MAX_ETHPORTS];
static uint8_t lkp_per_socket[NB_SOCKETS];
struct l3fwd_lkp_mode {
+ void (*read_config_files)(void);
void (*setup)(int);
int (*check_ptype)(int);
rte_rx_callback_fn cb_parse_ptype;
int (*main_loop)(void *);
void* (*get_ipv4_lookup_struct)(int);
void* (*get_ipv6_lookup_struct)(int);
+ void (*free_routes)(void);
};
static struct l3fwd_lkp_mode l3fwd_lkp;
static struct l3fwd_lkp_mode l3fwd_em_lkp = {
+ .read_config_files = read_config_files_em,
.setup = setup_hash,
.check_ptype = em_check_ptype,
.cb_parse_ptype = em_cb_parse_ptype,
.main_loop = em_main_loop,
.get_ipv4_lookup_struct = em_get_ipv4_l3fwd_lookup_struct,
.get_ipv6_lookup_struct = em_get_ipv6_l3fwd_lookup_struct,
+ .free_routes = em_free_routes,
};
static struct l3fwd_lkp_mode l3fwd_lpm_lkp = {
+ .read_config_files = read_config_files_lpm,
.setup = setup_lpm,
.check_ptype = lpm_check_ptype,
.cb_parse_ptype = lpm_cb_parse_ptype,
.main_loop = lpm_main_loop,
.get_ipv4_lookup_struct = lpm_get_ipv4_l3fwd_lookup_struct,
.get_ipv6_lookup_struct = lpm_get_ipv6_l3fwd_lookup_struct,
+ .free_routes = lpm_free_routes,
};
static struct l3fwd_lkp_mode l3fwd_fib_lkp = {
+ .read_config_files = read_config_files_lpm,
.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,
+ .free_routes = lpm_free_routes,
};
/*
@@ -224,6 +234,21 @@ const struct ipv6_l3fwd_route ipv6_l3fwd_route_array[] = {
{{32, 1, 2, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0}, 64, 15},
};
+/*
+ * API's called during initialization to setup ACL/EM/LPM rules.
+ */
+static void
+l3fwd_set_rule_ipv4_name(const char *optarg)
+{
+ parm_config.rule_ipv4_name = optarg;
+}
+
+static void
+l3fwd_set_rule_ipv6_name(const char *optarg)
+{
+ parm_config.rule_ipv6_name = optarg;
+}
+
/*
* Setup lookup methods for forwarding.
* Currently exact-match, longest-prefix-match and forwarding information
@@ -339,6 +364,8 @@ print_usage(const char *prgname)
{
fprintf(stderr, "%s [EAL options] --"
" -p PORTMASK"
+ " --rule_ipv4=FILE"
+ " --rule_ipv6=FILE"
" [-P]"
" [--lookup]"
" --config (port,queue,lcore)[,(port,queue,lcore)]"
@@ -381,7 +408,10 @@ print_usage(const char *prgname)
" --event-vector-size: Max vector size if event vectorization is enabled.\n"
" --event-vector-tmo: Max timeout to form vector in nanoseconds if event vectorization is enabled\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",
+ " -L : Enable longest prefix match, legacy flag please use --lookup=lpm instead\n"
+ " --rule_ipv4=FILE: Specify the ipv4 rules entries file.\n"
+ " Each rule occupies one line.\n"
+ " --rule_ipv6=FILE: Specify the ipv6 rules entries file.\n\n",
prgname);
}
@@ -596,6 +626,8 @@ static const char short_options[] =
#define CMD_LINE_OPT_ENABLE_VECTOR "event-vector"
#define CMD_LINE_OPT_VECTOR_SIZE "event-vector-size"
#define CMD_LINE_OPT_VECTOR_TMO_NS "event-vector-tmo"
+#define CMD_LINE_OPT_RULE_IPV4 "rule_ipv4"
+#define CMD_LINE_OPT_RULE_IPV6 "rule_ipv6"
enum {
/* long options mapped to a short option */
@@ -610,6 +642,8 @@ enum {
CMD_LINE_OPT_MAX_PKT_LEN_NUM,
CMD_LINE_OPT_HASH_ENTRY_NUM_NUM,
CMD_LINE_OPT_PARSE_PTYPE_NUM,
+ CMD_LINE_OPT_RULE_IPV4_NUM,
+ CMD_LINE_OPT_RULE_IPV6_NUM,
CMD_LINE_OPT_PARSE_PER_PORT_POOL,
CMD_LINE_OPT_MODE_NUM,
CMD_LINE_OPT_EVENTQ_SYNC_NUM,
@@ -637,6 +671,8 @@ static const struct option lgopts[] = {
{CMD_LINE_OPT_ENABLE_VECTOR, 0, 0, CMD_LINE_OPT_ENABLE_VECTOR_NUM},
{CMD_LINE_OPT_VECTOR_SIZE, 1, 0, CMD_LINE_OPT_VECTOR_SIZE_NUM},
{CMD_LINE_OPT_VECTOR_TMO_NS, 1, 0, CMD_LINE_OPT_VECTOR_TMO_NS_NUM},
+ {CMD_LINE_OPT_RULE_IPV4, 1, 0, CMD_LINE_OPT_RULE_IPV4_NUM},
+ {CMD_LINE_OPT_RULE_IPV6, 1, 0, CMD_LINE_OPT_RULE_IPV6_NUM},
{NULL, 0, 0, 0}
};
@@ -791,6 +827,12 @@ parse_args(int argc, char **argv)
case CMD_LINE_OPT_VECTOR_TMO_NS_NUM:
evt_rsrc->vector_tmo_ns = strtoull(optarg, NULL, 10);
break;
+ case CMD_LINE_OPT_RULE_IPV4_NUM:
+ l3fwd_set_rule_ipv4_name(optarg);
+ break;
+ case CMD_LINE_OPT_RULE_IPV6_NUM:
+ l3fwd_set_rule_ipv6_name(optarg);
+ break;
default:
print_usage(prgname);
return -1;
@@ -1358,6 +1400,24 @@ l3fwd_event_service_setup(void)
}
}
+/* Bypass comment and empty lines */
+int
+is_bypass_line(const char *buff)
+{
+ int i = 0;
+
+ /* comment line */
+ if (buff[0] == COMMENT_LEAD_CHAR)
+ return 1;
+ /* empty line */
+ while (buff[i] != '\0') {
+ if (!isspace(buff[i]))
+ return 0;
+ i++;
+ }
+ return 1;
+}
+
int
main(int argc, char **argv)
{
@@ -1395,6 +1455,9 @@ main(int argc, char **argv)
/* Setup function pointers for lookup method. */
setup_l3fwd_lookup_tables();
+ /* Add the config file rules */
+ l3fwd_lkp.read_config_files();
+
evt_rsrc->per_port_pool = per_port_pool;
evt_rsrc->pkt_pool = pktmbuf_pool;
evt_rsrc->vec_pool = vector_pool;
@@ -1501,6 +1564,9 @@ main(int argc, char **argv)
}
}
+ /* clean up config file routes */
+ l3fwd_lkp.free_routes();
+
/* clean up the EAL */
rte_eal_cleanup();
--
2.25.1
next prev parent reply other threads:[~2022-02-04 19:59 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-16 15:01 [PATCH v1 0/2] Add config file support for l3fwd Sean Morrissey
2021-12-16 15:01 ` [PATCH v1 1/2] examples/l3fwd: add config file support for LPM/FIB Sean Morrissey
2021-12-16 15:01 ` [PATCH v1 2/2] examples/l3fwd: add config file support for EM Sean Morrissey
2021-12-20 11:08 ` [PATCH v2 0/2] Add config file support for l3fwd Sean Morrissey
2021-12-20 11:08 ` [PATCH v2 1/2] examples/l3fwd: add config file support for LPM/FIB Sean Morrissey
2021-12-20 15:42 ` Ananyev, Konstantin
2021-12-20 11:08 ` [PATCH v2 2/2] examples/l3fwd: add config file support for EM Sean Morrissey
2021-12-20 15:53 ` Ananyev, Konstantin
2021-12-21 12:30 ` [PATCH v3 0/2] Add config file support for l3fwd Sean Morrissey
2021-12-21 12:30 ` [PATCH v3 1/2] examples/l3fwd: add config file support for LPM/FIB Sean Morrissey
2021-12-21 12:30 ` [PATCH v3 2/2] examples/l3fwd: add config file support for EM Sean Morrissey
2022-01-10 14:00 ` Ananyev, Konstantin
2022-01-26 12:44 ` [PATCH v4 0/2] Add config file support for l3fwd Sean Morrissey
2022-01-26 12:44 ` [PATCH v4 1/2] examples/l3fwd: add config file support for LPM/FIB Sean Morrissey
2022-01-26 12:44 ` [PATCH v4 2/2] examples/l3fwd: add config file support for EM Sean Morrissey
2022-02-04 19:59 ` [PATCH v5 0/2] Add config file support for l3fwd Sean Morrissey
2022-02-04 19:59 ` Sean Morrissey [this message]
2022-02-08 2:21 ` [PATCH v5 1/2] examples/l3fwd: add config file support for LPM/FIB Han, YingyaX
2022-02-04 19:59 ` [PATCH v5 2/2] examples/l3fwd: add config file support for EM Sean Morrissey
2022-02-04 22:26 ` [PATCH v5 0/2] Add config file support for l3fwd Stephen Hemminger
2022-02-06 15:16 ` Ananyev, Konstantin
2022-02-08 3:04 ` Stephen Hemminger
2022-02-08 10:44 ` Ananyev, Konstantin
2022-02-08 16:15 ` Medvedkin, Vladimir
2022-02-08 17:49 ` Stephen Hemminger
2022-02-08 18:10 ` Bruce Richardson
2022-02-09 12:00 ` Ananyev, Konstantin
2022-02-09 13:54 ` Bruce Richardson
2022-02-09 16:00 ` Medvedkin, Vladimir
2022-02-22 9:59 ` Thomas Monjalon
2022-02-22 10:39 ` Ananyev, Konstantin
2022-02-22 13:46 ` Thomas Monjalon
2022-02-22 15:13 ` Ananyev, Konstantin
2022-02-22 16:48 ` Thomas Monjalon
2022-02-24 11:06 ` Ananyev, Konstantin
2022-02-24 13:46 ` Thomas Monjalon
2022-02-24 13:58 ` Bruce Richardson
2022-02-25 10:36 ` Ananyev, Konstantin
2022-02-25 10:40 ` Bruce Richardson
2022-02-25 12:21 ` Ananyev, Konstantin
2022-02-25 12:50 ` Morten Brørup
2022-02-25 5:18 ` Honnappa Nagarahalli
2022-03-01 14:49 ` [PATCH v6 " Sean Morrissey
2022-03-01 14:49 ` [PATCH v6 1/2] examples/l3fwd: add config file support for LPM/FIB Sean Morrissey
2022-03-01 14:49 ` [PATCH v6 2/2] examples/l3fwd: add config file support for EM Sean Morrissey
2022-03-08 8:57 ` [PATCH v6 0/2] Add config file support for l3fwd Thomas Monjalon
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220204195905.449192-2-sean.morrissey@intel.com \
--to=sean.morrissey@intel.com \
--cc=dev@dpdk.org \
--cc=konstantin.ananyev@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).