|SUCCESS| fib,rib: implement full network order support for IPv4
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Mon May 18 15:39:08 CEST 2026
Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/164054
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-05-18
This patch introduces network byte order support for IPv4 addresses in the FIB and RIB libraries. I'll review it for correctness bugs, coding style issues, and API requirements.
git sha: (not provided in patch)
Author: Robin Jarry <rjarry at redhat.com>
Subject: [PATCH dpdk] fib,rib: implement full network order support for IPv4
The patch extends network byte order handling in FIB/RIB from lookup-only
to all user-facing API functions. It renames RTE_FIB_F_LOOKUP_NETWORK_ORDER
to RTE_FIB_F_NETWORK_ORDER and adds RTE_RIB_F_NETWORK_ORDER.
> 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,
Does this code handle the depth parameter correctly with network order?
The depth is a prefix length that should be byte-order independent, but
does rte_rib_get_nxt() expect it to work correctly when the IP is in
network order?
[ ... ]
> @@ -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);
Is dp->be_addr being validated against the RIB's network order flag?
When creating a FIB with RTE_FIB_F_NETWORK_ORDER, does the code ensure
that its internal RIB object has RTE_RIB_F_NETWORK_ORDER set? This
consistency is mentioned in the commit message but should be verified.
> 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
> @@ -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;
Does this code properly preserve any other RIB flags that might already
be set in rib_conf.flags? The assignment here overwrites rib_conf.flags
completely rather than using |= to preserve existing flags.
> 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)
Is the deprecation notice syntactically correct? The RTE_DEPRECATED
macro typically takes a string message as argument, not just a name.
Should this be RTE_DEPRECATED("use RTE_FIB_F_NETWORK_ORDER instead")?
> 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
> @@ -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)
Is there a potential collision between RIB_NODE_NET_ORDER and other
node flag bits? The code uses node->flag to store both RTE_RIB_VALID_NODE
and RIB_NODE_NET_ORDER, but are these flag bits properly isolated?
> @@ -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;
> + }
> +
Does this conversion occur at the right time? The ip is masked with
rte_rib_depth_to_mask(depth) later in the function. Should the conversion
happen before or after masking?
> @@ -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;
Does this code handle the case where the existing node has different
byte order flags than the new insertion? Can we OR in net_order to a
node that might have been created with a different byte order setting?
> @@ -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);
Is this the correct approach for rte_rib_get_ip()? The function takes
only a node pointer, not a rib pointer, so it relies on per-node flags.
Can this lead to inconsistencies if nodes from different RIBs with
different byte order settings are mixed?
> @@ -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);
Does this code properly handle the byte order conversion when freeing
the RIB? The __rib_remove() function now expects host byte order, and
tmp->ip is stored in host order, so this should be correct, but can
you verify this call chain?
More information about the test-report
mailing list