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 <[email protected]>
---
 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

Reply via email to