[PATCH dpdk] fib,rib: implement full network order support for IPv4
Robin Jarry
rjarry at redhat.com
Mon May 18 10:39:37 CEST 2026
Control plane stacks deal exclusively with network byte order addresses.
The existing RTE_FIB_F_LOOKUP_NETWORK_ORDER flag only covers datapath
lookups, forcing callers to convert every address back and forth when
adding or deleting routes.
Rename RTE_FIB_F_LOOKUP_NETWORK_ORDER to RTE_FIB_F_NETWORK_ORDER (keep
the old name with a deprecation notice) and add a new opt-in flag:
RTE_RIB_F_NETWORK_ORDER.
When these flags are specified, *all* user-facing IPv4 functions accept
and return addresses in network byte order. Internally, both libraries
keep operating in host order; the conversion happens at the public API
boundary only.
For rte_rib, a per-node flag bit tracks whether rte_rib_get_ip()
should convert back to network order, since that function does not
take a rib pointer.
When creating a FIB with RTE_FIB_F_NETWORK_ORDER, make sure that its
internal RIB object has the corresponding RTE_RIB_F_NETWORK_ORDER.
Signed-off-by: Robin Jarry <rjarry at redhat.com>
---
app/test/test_fib.c | 80 +++++++++++++++++++++++++++++++++++++++++++++
app/test/test_rib.c | 59 +++++++++++++++++++++++++++++++++
lib/fib/dir24_8.c | 29 ++++++++++++----
lib/fib/dir24_8.h | 1 +
lib/fib/rte_fib.c | 6 ++--
lib/fib/rte_fib.h | 8 +++--
lib/rib/rte_rib.c | 74 +++++++++++++++++++++++++++++++----------
lib/rib/rte_rib.h | 5 +++
8 files changed, 233 insertions(+), 29 deletions(-)
diff --git a/app/test/test_fib.c b/app/test/test_fib.c
index bd73399d565c..84b57eef3b5a 100644
--- a/app/test/test_fib.c
+++ b/app/test/test_fib.c
@@ -7,6 +7,7 @@
#include <stdint.h>
#include <stdlib.h>
+#include <rte_byteorder.h>
#include <rte_ip.h>
#include <rte_log.h>
#include <rte_fib.h>
@@ -24,6 +25,7 @@ static int32_t test_get_invalid(void);
static int32_t test_lookup(void);
static int32_t test_invalid_rcu(void);
static int32_t test_fib_rcu_sync_rw(void);
+static int32_t test_network_order(void);
#define MAX_ROUTES (1 << 16)
#define MAX_TBL8 (1 << 15)
@@ -588,6 +590,83 @@ test_fib_rcu_sync_rw(void)
return status == 0 ? TEST_SUCCESS : TEST_FAILED;
}
+int32_t
+test_network_order(void)
+{
+ struct rte_fib *fib = NULL;
+ struct rte_fib_conf config = { 0 };
+ uint32_t ip_he = RTE_IPV4(192, 0, 2, 0);
+ uint32_t ip_be = rte_cpu_to_be_32(ip_he);
+ uint32_t ip_miss_be = rte_cpu_to_be_32(RTE_IPV4(10, 0, 0, 1));
+ uint64_t def_nh = 100;
+ uint64_t nh_set = 42;
+ uint64_t nh_arr[3];
+ uint32_t ip_arr[3];
+ int ret;
+
+ config.max_routes = MAX_ROUTES;
+ config.rib_ext_sz = 0;
+ config.default_nh = def_nh;
+ config.type = RTE_FIB_DUMMY;
+ config.flags = RTE_FIB_F_NETWORK_ORDER;
+
+ fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config);
+ RTE_TEST_ASSERT(fib != NULL, "Failed to create FIB\n");
+
+ ret = rte_fib_add(fib, ip_be, 24, nh_set);
+ RTE_TEST_ASSERT(ret == 0, "Failed to add route\n");
+
+ ip_arr[0] = ip_be;
+ ip_arr[1] = rte_cpu_to_be_32(RTE_IPV4(192, 0, 2, 123));
+ ip_arr[2] = ip_miss_be;
+
+ ret = rte_fib_lookup_bulk(fib, ip_arr, nh_arr, 3);
+ RTE_TEST_ASSERT(ret == 0, "Failed to lookup\n");
+ RTE_TEST_ASSERT(nh_arr[0] == nh_set,
+ "Failed to get proper nexthop for prefix\n");
+ RTE_TEST_ASSERT(nh_arr[1] == nh_set,
+ "Failed to get proper nexthop for covered IP\n");
+ RTE_TEST_ASSERT(nh_arr[2] == def_nh,
+ "Failed to get default nexthop for missing IP\n");
+
+ ret = rte_fib_delete(fib, ip_be, 24);
+ RTE_TEST_ASSERT(ret == 0, "Failed to delete route\n");
+
+ ret = rte_fib_lookup_bulk(fib, ip_arr, nh_arr, 1);
+ RTE_TEST_ASSERT(ret == 0, "Failed to lookup\n");
+ RTE_TEST_ASSERT(nh_arr[0] == def_nh,
+ "Failed to get default nexthop after delete\n");
+
+ rte_fib_free(fib);
+
+ /* repeat with DIR24_8 */
+ config.type = RTE_FIB_DIR24_8;
+ config.dir24_8.nh_sz = RTE_FIB_DIR24_8_4B;
+ config.dir24_8.num_tbl8 = MAX_TBL8;
+
+ fib = rte_fib_create(__func__, SOCKET_ID_ANY, &config);
+ RTE_TEST_ASSERT(fib != NULL, "Failed to create DIR24_8 FIB\n");
+
+ ret = rte_fib_add(fib, ip_be, 24, nh_set);
+ RTE_TEST_ASSERT(ret == 0, "Failed to add route\n");
+
+ ret = rte_fib_lookup_bulk(fib, ip_arr, nh_arr, 3);
+ RTE_TEST_ASSERT(ret == 0, "Failed to lookup\n");
+ RTE_TEST_ASSERT(nh_arr[0] == nh_set,
+ "Failed to get proper nexthop for prefix\n");
+ RTE_TEST_ASSERT(nh_arr[1] == nh_set,
+ "Failed to get proper nexthop for covered IP\n");
+ RTE_TEST_ASSERT(nh_arr[2] == def_nh,
+ "Failed to get default nexthop for missing IP\n");
+
+ ret = rte_fib_delete(fib, ip_be, 24);
+ RTE_TEST_ASSERT(ret == 0, "Failed to delete route\n");
+
+ rte_fib_free(fib);
+
+ return TEST_SUCCESS;
+}
+
static struct unit_test_suite fib_fast_tests = {
.suite_name = "fib autotest",
.setup = NULL,
@@ -600,6 +679,7 @@ static struct unit_test_suite fib_fast_tests = {
TEST_CASE(test_lookup),
TEST_CASE(test_invalid_rcu),
TEST_CASE(test_fib_rcu_sync_rw),
+ TEST_CASE(test_network_order),
TEST_CASES_END()
}
};
diff --git a/app/test/test_rib.c b/app/test/test_rib.c
index a4a683140df3..200533e84e09 100644
--- a/app/test/test_rib.c
+++ b/app/test/test_rib.c
@@ -21,6 +21,7 @@ static int32_t test_insert_invalid(void);
static int32_t test_get_fn(void);
static int32_t test_basic(void);
static int32_t test_tree_traversal(void);
+static int32_t test_network_order(void);
#define MAX_DEPTH 32
#define MAX_RULES (1 << 22)
@@ -323,6 +324,63 @@ test_tree_traversal(void)
return TEST_SUCCESS;
}
+int32_t
+test_network_order(void)
+{
+ struct rte_rib *rib = NULL;
+ struct rte_rib_node *node;
+ struct rte_rib_conf config;
+
+ uint32_t ip_he = RTE_IPV4(192, 0, 2, 0);
+ uint32_t ip_be = rte_cpu_to_be_32(ip_he);
+ uint32_t ip_ret;
+ uint64_t nh_set = 42;
+ uint64_t nh_ret;
+ uint8_t depth = 24;
+ int ret;
+
+ config.max_nodes = MAX_RULES;
+ config.ext_sz = 0;
+ config.flags = RTE_RIB_F_NETWORK_ORDER;
+
+ rib = rte_rib_create(__func__, SOCKET_ID_ANY, &config);
+ RTE_TEST_ASSERT(rib != NULL, "Failed to create RIB\n");
+
+ node = rte_rib_insert(rib, ip_be, depth);
+ RTE_TEST_ASSERT(node != NULL, "Failed to insert rule\n");
+
+ ret = rte_rib_set_nh(node, nh_set);
+ RTE_TEST_ASSERT(ret == 0, "Failed to set nh\n");
+
+ /* lookup with network-order IP */
+ node = rte_rib_lookup(rib, ip_be);
+ RTE_TEST_ASSERT(node != NULL, "Failed to lookup\n");
+
+ ret = rte_rib_get_nh(node, &nh_ret);
+ RTE_TEST_ASSERT((ret == 0) && (nh_ret == nh_set),
+ "Failed to get proper nexthop\n");
+
+ /* get_ip must return network-order IP */
+ ret = rte_rib_get_ip(node, &ip_ret);
+ RTE_TEST_ASSERT((ret == 0) && (ip_ret == ip_be),
+ "Failed to get proper IP in network order\n");
+
+ /* exact lookup with network-order IP */
+ node = rte_rib_lookup_exact(rib, ip_be, depth);
+ RTE_TEST_ASSERT(node != NULL, "Failed to exact lookup\n");
+
+ /* remove with network-order IP */
+ rte_rib_remove(rib, ip_be, depth);
+
+ node = rte_rib_lookup(rib, ip_be);
+ RTE_TEST_ASSERT(node == NULL,
+ "Lookup returns non existent rule\n");
+
+ rte_rib_free(rib);
+
+ return TEST_SUCCESS;
+}
+
static struct unit_test_suite rib_tests = {
.suite_name = "rib autotest",
.setup = NULL,
@@ -334,6 +392,7 @@ static struct unit_test_suite rib_tests = {
TEST_CASE(test_get_fn),
TEST_CASE(test_basic),
TEST_CASE(test_tree_traversal),
+ TEST_CASE(test_network_order),
TEST_CASES_END()
}
};
diff --git a/lib/fib/dir24_8.c b/lib/fib/dir24_8.c
index 489d2ef427c6..781ecbe9e64e 100644
--- a/lib/fib/dir24_8.c
+++ b/lib/fib/dir24_8.c
@@ -414,24 +414,33 @@ install_to_fib(struct dir24_8_tbl *dp, uint32_t ledge, uint32_t redge,
return 0;
}
+/*
+ * modify_fib operates in host byte order. When the RIB carries the
+ * network-order flag, rte_rib_get_nxt/rte_rib_get_ip return addresses
+ * in network order, so this helper converts them back to host order
+ * for DIR24_8 table operations.
+ */
static int
modify_fib(struct dir24_8_tbl *dp, struct rte_rib *rib, uint32_t ip,
uint8_t depth, uint64_t next_hop)
{
struct rte_rib_node *tmp = NULL;
uint32_t ledge, redge, tmp_ip;
+ uint32_t rib_ip = dp->be_addr ? rte_cpu_to_be_32(ip) : ip;
int ret;
uint8_t tmp_depth;
ledge = ip;
do {
- tmp = rte_rib_get_nxt(rib, ip, depth, tmp,
+ tmp = rte_rib_get_nxt(rib, rib_ip, depth, tmp,
RTE_RIB_GET_NXT_COVER);
if (tmp != NULL) {
rte_rib_get_depth(tmp, &tmp_depth);
if (tmp_depth == depth)
continue;
rte_rib_get_ip(tmp, &tmp_ip);
+ if (dp->be_addr)
+ tmp_ip = rte_be_to_cpu_32(tmp_ip);
redge = tmp_ip & rte_rib_depth_to_mask(tmp_depth);
if (ledge == redge) {
ledge = redge +
@@ -475,6 +484,7 @@ dir24_8_modify(struct rte_fib *fib, uint32_t ip, uint8_t depth,
struct rte_rib_node *parent;
int ret = 0;
uint64_t par_nh, node_nh;
+ uint32_t ip_he;
if ((fib == NULL) || (depth > RTE_FIB_MAXDEPTH))
return -EINVAL;
@@ -486,7 +496,13 @@ dir24_8_modify(struct rte_fib *fib, uint32_t ip, uint8_t depth,
if (next_hop > get_max_nh(dp->nh_sz))
return -EINVAL;
- ip &= rte_rib_depth_to_mask(depth);
+ /*
+ * The RIB API handles byte order conversion when the
+ * network-order flag is set. DIR24_8 table operations
+ * require host-order addresses.
+ */
+ ip_he = dp->be_addr ? rte_be_to_cpu_32(ip) : ip;
+ ip_he &= rte_rib_depth_to_mask(depth);
node = rte_rib_lookup_exact(rib, ip, depth);
switch (op) {
@@ -495,7 +511,7 @@ dir24_8_modify(struct rte_fib *fib, uint32_t ip, uint8_t depth,
rte_rib_get_nh(node, &node_nh);
if (node_nh == next_hop)
return 0;
- ret = modify_fib(dp, rib, ip, depth, next_hop);
+ ret = modify_fib(dp, rib, ip_he, depth, next_hop);
if (ret == 0)
rte_rib_set_nh(node, next_hop);
return 0;
@@ -518,7 +534,7 @@ dir24_8_modify(struct rte_fib *fib, uint32_t ip, uint8_t depth,
if (par_nh == next_hop)
goto successfully_added;
}
- ret = modify_fib(dp, rib, ip, depth, next_hop);
+ ret = modify_fib(dp, rib, ip_he, depth, next_hop);
if (ret != 0) {
rte_rib_remove(rib, ip, depth);
return ret;
@@ -536,9 +552,9 @@ dir24_8_modify(struct rte_fib *fib, uint32_t ip, uint8_t depth,
rte_rib_get_nh(parent, &par_nh);
rte_rib_get_nh(node, &node_nh);
if (par_nh != node_nh)
- ret = modify_fib(dp, rib, ip, depth, par_nh);
+ ret = modify_fib(dp, rib, ip_he, depth, par_nh);
} else
- ret = modify_fib(dp, rib, ip, depth, dp->def_nh);
+ ret = modify_fib(dp, rib, ip_he, depth, dp->def_nh);
if (ret == 0) {
rte_rib_remove(rib, ip, depth);
if (depth > 24) {
@@ -606,6 +622,7 @@ dir24_8_create(const char *name, int socket_id, struct rte_fib_conf *fib_conf)
dp->def_nh = def_nh;
dp->nh_sz = nh_sz;
dp->number_tbl8s = num_tbl8;
+ dp->be_addr = !!(fib_conf->flags & RTE_FIB_F_NETWORK_ORDER);
snprintf(mem_name, sizeof(mem_name), "TBL8_idxes_%p", dp);
dp->tbl8_idxes = rte_zmalloc_socket(mem_name,
diff --git a/lib/fib/dir24_8.h b/lib/fib/dir24_8.h
index b343b5d6866d..d4fa248cfb88 100644
--- a/lib/fib/dir24_8.h
+++ b/lib/fib/dir24_8.h
@@ -33,6 +33,7 @@ struct dir24_8_tbl {
uint32_t rsvd_tbl8s; /**< Number of reserved tbl8s */
uint32_t cur_tbl8s; /**< Current number of tbl8s */
enum rte_fib_dir24_8_nh_sz nh_sz; /**< Size of nexthop entry */
+ bool be_addr; /**< User addresses in network order */
/* RCU config. */
enum rte_fib_qsbr_mode rcu_mode;/* Blocking, defer queue. */
struct rte_rcu_qsbr *v; /* RCU QSBR variable. */
diff --git a/lib/fib/rte_fib.c b/lib/fib/rte_fib.c
index 184210f38070..3e4c15cfc809 100644
--- a/lib/fib/rte_fib.c
+++ b/lib/fib/rte_fib.c
@@ -109,7 +109,7 @@ init_dataplane(struct rte_fib *fib, __rte_unused int socket_id,
if (fib->dp == NULL)
return -rte_errno;
fib->lookup = dir24_8_get_lookup_fn(fib->dp,
- RTE_FIB_LOOKUP_DEFAULT, !!(fib->flags & RTE_FIB_F_LOOKUP_NETWORK_ORDER));
+ RTE_FIB_LOOKUP_DEFAULT, !!(fib->flags & RTE_FIB_F_NETWORK_ORDER));
fib->modify = dir24_8_modify;
return 0;
default:
@@ -172,6 +172,8 @@ rte_fib_create(const char *name, int socket_id, struct rte_fib_conf *conf)
rib_conf.ext_sz = conf->rib_ext_sz;
rib_conf.max_nodes = conf->max_routes * 2;
+ rib_conf.flags = (conf->flags & RTE_FIB_F_NETWORK_ORDER) ?
+ RTE_RIB_F_NETWORK_ORDER : 0;
rib = rte_rib_create(name, socket_id, &rib_conf);
if (rib == NULL) {
@@ -340,7 +342,7 @@ rte_fib_select_lookup(struct rte_fib *fib,
switch (fib->type) {
case RTE_FIB_DIR24_8:
fn = dir24_8_get_lookup_fn(fib->dp, type,
- !!(fib->flags & RTE_FIB_F_LOOKUP_NETWORK_ORDER));
+ !!(fib->flags & RTE_FIB_F_NETWORK_ORDER));
if (fn == NULL)
return -EINVAL;
fib->lookup = fn;
diff --git a/lib/fib/rte_fib.h b/lib/fib/rte_fib.h
index b16a653535cf..5542e735b6f3 100644
--- a/lib/fib/rte_fib.h
+++ b/lib/fib/rte_fib.h
@@ -91,9 +91,11 @@ enum rte_fib_lookup_type {
/**< Vector implementation using AVX512 */
};
-/** If set, fib lookup is expecting IPv4 address in network byte order */
-#define RTE_FIB_F_LOOKUP_NETWORK_ORDER 1
-#define RTE_FIB_ALLOWED_FLAGS (RTE_FIB_F_LOOKUP_NETWORK_ORDER)
+/** If set, all user-facing IPv4 addresses are in network byte order */
+#define RTE_FIB_F_NETWORK_ORDER 1
+#define RTE_FIB_F_LOOKUP_NETWORK_ORDER \
+ (RTE_DEPRECATED(RTE_FIB_F_LOOKUP_NETWORK_ORDER) RTE_FIB_F_NETWORK_ORDER)
+#define RTE_FIB_ALLOWED_FLAGS (RTE_FIB_F_NETWORK_ORDER)
/** FIB configuration structure */
struct rte_fib_conf {
diff --git a/lib/rib/rte_rib.c b/lib/rib/rte_rib.c
index 046db131ca00..c6dbe684d211 100644
--- a/lib/rib/rte_rib.c
+++ b/lib/rib/rte_rib.c
@@ -8,6 +8,7 @@
#include <sys/queue.h>
#include <eal_export.h>
+#include <rte_byteorder.h>
#include <rte_eal_memconfig.h>
#include <rte_errno.h>
#include <rte_malloc.h>
@@ -28,6 +29,8 @@ static struct rte_tailq_elem rte_rib_tailq = {
EAL_REGISTER_TAILQ(rte_rib_tailq)
#define RTE_RIB_VALID_NODE 1
+#define RIB_NODE_NET_ORDER 2
+#define RTE_RIB_ALLOWED_FLAGS (RTE_RIB_F_NETWORK_ORDER)
/* Maximum depth value possible for IPv4 RIB. */
#define RIB_MAXDEPTH 32
/* Maximum length of a RIB name. */
@@ -51,6 +54,7 @@ struct rte_rib {
uint32_t cur_nodes;
uint32_t cur_routes;
uint32_t max_nodes;
+ unsigned int flags;
};
static inline bool
@@ -112,6 +116,8 @@ rte_rib_lookup(struct rte_rib *rib, uint32_t ip)
rte_errno = EINVAL;
return NULL;
}
+ if (rib->flags & RTE_RIB_F_NETWORK_ORDER)
+ ip = rte_be_to_cpu_32(ip);
cur = rib->tree;
while ((cur != NULL) && is_covered(ip, cur->ip, cur->depth)) {
@@ -162,6 +168,8 @@ rte_rib_lookup_exact(struct rte_rib *rib, uint32_t ip, uint8_t depth)
rte_errno = EINVAL;
return NULL;
}
+ if (rib->flags & RTE_RIB_F_NETWORK_ORDER)
+ ip = rte_be_to_cpu_32(ip);
ip &= rte_rib_depth_to_mask(depth);
return __rib_lookup_exact(rib, ip, depth);
@@ -172,18 +180,12 @@ rte_rib_lookup_exact(struct rte_rib *rib, uint32_t ip, uint8_t depth)
* for a given in args ip/depth prefix
* last = NULL means the first invocation
*/
-RTE_EXPORT_SYMBOL(rte_rib_get_nxt)
-struct rte_rib_node *
-rte_rib_get_nxt(struct rte_rib *rib, uint32_t ip,
+static struct rte_rib_node *
+__rib_get_nxt(struct rte_rib *rib, uint32_t ip,
uint8_t depth, struct rte_rib_node *last, int flag)
{
struct rte_rib_node *tmp, *prev = NULL;
- if (unlikely(rib == NULL || depth > RIB_MAXDEPTH)) {
- rte_errno = EINVAL;
- return NULL;
- }
-
if (last == NULL) {
tmp = rib->tree;
while ((tmp) && (tmp->depth < depth))
@@ -213,13 +215,28 @@ rte_rib_get_nxt(struct rte_rib *rib, uint32_t ip,
return prev;
}
-RTE_EXPORT_SYMBOL(rte_rib_remove)
-void
-rte_rib_remove(struct rte_rib *rib, uint32_t ip, uint8_t depth)
+RTE_EXPORT_SYMBOL(rte_rib_get_nxt)
+struct rte_rib_node *
+rte_rib_get_nxt(struct rte_rib *rib, uint32_t ip,
+ uint8_t depth, struct rte_rib_node *last, int flag)
+{
+ if (unlikely(rib == NULL || depth > RIB_MAXDEPTH)) {
+ rte_errno = EINVAL;
+ return NULL;
+ }
+ if (rib->flags & RTE_RIB_F_NETWORK_ORDER)
+ ip = rte_be_to_cpu_32(ip);
+
+ return __rib_get_nxt(rib, ip, depth, last, flag);
+}
+
+static void
+__rib_remove(struct rte_rib *rib, uint32_t ip, uint8_t depth)
{
struct rte_rib_node *cur, *prev, *child;
- cur = rte_rib_lookup_exact(rib, ip, depth);
+ ip &= rte_rib_depth_to_mask(depth);
+ cur = __rib_lookup_exact(rib, ip, depth);
if (cur == NULL)
return;
@@ -246,6 +263,17 @@ rte_rib_remove(struct rte_rib *rib, uint32_t ip, uint8_t depth)
}
}
+RTE_EXPORT_SYMBOL(rte_rib_remove)
+void
+rte_rib_remove(struct rte_rib *rib, uint32_t ip, uint8_t depth)
+{
+ if (unlikely(rib == NULL || depth > RIB_MAXDEPTH))
+ return;
+ if (rib->flags & RTE_RIB_F_NETWORK_ORDER)
+ ip = rte_be_to_cpu_32(ip);
+ __rib_remove(rib, ip, depth);
+}
+
RTE_EXPORT_SYMBOL(rte_rib_insert)
struct rte_rib_node *
rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth)
@@ -257,12 +285,18 @@ rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth)
int d = 0;
uint32_t common_prefix;
uint8_t common_depth;
+ uint8_t net_order = 0;
if (unlikely(rib == NULL || depth > RIB_MAXDEPTH)) {
rte_errno = EINVAL;
return NULL;
}
+ if (rib->flags & RTE_RIB_F_NETWORK_ORDER) {
+ ip = rte_be_to_cpu_32(ip);
+ net_order = RIB_NODE_NET_ORDER;
+ }
+
tmp = &rib->tree;
ip &= rte_rib_depth_to_mask(depth);
new_node = __rib_lookup_exact(rib, ip, depth);
@@ -281,7 +315,7 @@ rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth)
new_node->parent = NULL;
new_node->ip = ip;
new_node->depth = depth;
- new_node->flag = RTE_RIB_VALID_NODE;
+ new_node->flag = RTE_RIB_VALID_NODE | net_order;
/* traverse down the tree to find matching node or closest matching */
while (1) {
@@ -300,7 +334,7 @@ rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth)
*/
if ((ip == (*tmp)->ip) && (depth == (*tmp)->depth)) {
node_free(rib, new_node);
- (*tmp)->flag |= RTE_RIB_VALID_NODE;
+ (*tmp)->flag |= RTE_RIB_VALID_NODE | net_order;
++rib->cur_routes;
return *tmp;
}
@@ -336,7 +370,7 @@ rte_rib_insert(struct rte_rib *rib, uint32_t ip, uint8_t depth)
}
common_node->ip = common_prefix;
common_node->depth = common_depth;
- common_node->flag = 0;
+ common_node->flag = net_order;
common_node->parent = (*tmp)->parent;
new_node->parent = common_node;
(*tmp)->parent = common_node;
@@ -362,6 +396,8 @@ rte_rib_get_ip(const struct rte_rib_node *node, uint32_t *ip)
return -1;
}
*ip = node->ip;
+ if (node->flag & RIB_NODE_NET_ORDER)
+ *ip = rte_cpu_to_be_32(*ip);
return 0;
}
@@ -419,7 +455,8 @@ rte_rib_create(const char *name, int socket_id, const struct rte_rib_conf *conf)
struct rte_mempool *node_pool;
/* Check user arguments. */
- if (unlikely(name == NULL || conf == NULL || conf->max_nodes <= 0)) {
+ if (unlikely(name == NULL || conf == NULL || conf->max_nodes <= 0 ||
+ (conf->flags & ~RTE_RIB_ALLOWED_FLAGS))) {
rte_errno = EINVAL;
return NULL;
}
@@ -473,6 +510,7 @@ rte_rib_create(const char *name, int socket_id, const struct rte_rib_conf *conf)
rte_strlcpy(rib->name, name, sizeof(rib->name));
rib->tree = NULL;
rib->max_nodes = conf->max_nodes;
+ rib->flags = conf->flags;
rib->node_pool = node_pool;
te->data = (void *)rib;
TAILQ_INSERT_TAIL(rib_list, te, next);
@@ -541,9 +579,9 @@ rte_rib_free(struct rte_rib *rib)
rte_mcfg_tailq_write_unlock();
- while ((tmp = rte_rib_get_nxt(rib, 0, 0, tmp,
+ while ((tmp = __rib_get_nxt(rib, 0, 0, tmp,
RTE_RIB_GET_NXT_ALL)) != NULL)
- rte_rib_remove(rib, tmp->ip, tmp->depth);
+ __rib_remove(rib, tmp->ip, tmp->depth);
rte_mempool_free(rib->node_pool);
rte_free(rib);
diff --git a/lib/rib/rte_rib.h b/lib/rib/rte_rib.h
index c325b3e3618c..085e507508be 100644
--- a/lib/rib/rte_rib.h
+++ b/lib/rib/rte_rib.h
@@ -17,6 +17,7 @@
#include <stdlib.h>
#include <stdint.h>
+#include <rte_byteorder.h>
#include <rte_common.h>
#ifdef __cplusplus
@@ -36,6 +37,9 @@ enum {
struct rte_rib;
struct rte_rib_node;
+/** If set, all user-facing IPv4 addresses are in network byte order */
+#define RTE_RIB_F_NETWORK_ORDER 1
+
/** RIB configuration structure */
struct rte_rib_conf {
/**
@@ -46,6 +50,7 @@ struct rte_rib_conf {
size_t ext_sz;
/* size of rte_rib_node's pool */
int max_nodes;
+ unsigned int flags; /**< Optional feature flags from RTE_RIB_F_* */
};
/**
--
2.54.0
More information about the dev
mailing list