[PATCH dpdk] fib,rib: implement full network order support for IPv4
Medvedkin, Vladimir
vladimir.medvedkin at intel.com
Wed Sep 30 19:12:36 CEST 2026
Hi Robin,
Thanks for the patch.
check-git-log.sh reports
Wrong headline format:
fib,rib: implement full network order support for IPv4
could you please split for 2 patches?
A few comments inline.
Also reflect changes in release notes please.
On 5/18/2026 9:39 AM, Robin Jarry wrote:
> 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");
it is probably worth to add an extra more specific route to better
coverage. Or keep RIB in host order and byteswap inside the
rte_fib_add() as I suggested below
> +
> + 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);
just a nit: ip_he does it stands for "host endian"? ip_ho instead for
"host order"?
> + 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
nit: rte_rib_get_nxt() does not return address directly. It accepts it as an argument
> + * 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;
do we really need to align the RIB and FIB byte order? Since the RIB
structure is internal, why not keep it in host order and byteswap just
once at the API boundary, i.e. in _fib_add/del? In that case, we
wouldn’t need to touch the internal algorithm-specific code (dir24_8).
This would make things an order of magnitude simpler and cleaner.
>
> 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)
I'd suggest to keep 2 flags at the moment - the old one just for lookup
and a new one for lookup and control plane operations
> +#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
RTE_RIB_NET_ORDER_NODE, just to avoid confusion with current naming?
Also since this is a bit flag it would be better to define it via bit
shift instead of a power of 2 digit
> +#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);
plz reflect this change of behavior in doxygen
> 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>
why include it here in .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_* */
old tests (and all possible places we're using rte_rib_conf struct)
should be updated to account for this new flag
> };
>
> /**
--
Regards,
Vladimir
More information about the dev
mailing list