|SUCCESS| [v1] fib6: fix sign conversion of tbl8 indexes
dpdklab at iol.unh.edu
dpdklab at iol.unh.edu
Wed Oct 21 20:25:09 CEST 2026
Test-Label: ai-code-review
Test-Status: SUCCESS
https://dpdk.org/patch/171819
_AI Code Review_
=== Patch Review: series.patch (via Claude) ===
Review date: 2026-10-21
# DPDK Patch Review
## ERRORS
**Integer shift overflow in two locations:**
In `build_common_root()` at line 332 and in `write_edge()` at line 363, `tbl8_idx` (type `int`) is left-shifted by 1 before being widened to `uint64_t`. When `tbl8_idx` is negative (error return from `tbl8_alloc()`) or has bit 30 set, the shift overflows in `int` before the result is widened.
The patch correctly adds casts to `uint64_t` before shifting at both locations:
```c
write_to_dp(tbl_ptr, ((uint64_t)tbl8_idx << 1) |
TRIE_EXT_ENT, dp->nh_sz, 1);
```
and
```c
val = ((uint64_t)tbl8_idx << 1) | TRIE_EXT_ENT;
```
However, **`tbl8_idx` can still be negative at the shift** in `write_edge()` if `tbl8_alloc()` fails. The error check at line 361-362 only applies when `(val & TRIE_EXT_ENT) != TRIE_EXT_ENT`. When the condition is true, `tbl8_idx` is assigned the result of `tbl8_alloc()` at line 360, but there is no error check before using it at line 363. If `tbl8_alloc()` returns -ENOSPC, `tbl8_idx` is negative and shifting it is undefined behavior.
**Suggested fix:** Add an error check after the `tbl8_alloc()` call in `write_edge()`:
```c
if ((val & TRIE_EXT_ENT) != TRIE_EXT_ENT) {
tbl8_idx = tbl8_alloc(dp, val);
if (tbl8_idx < 0)
return tbl8_idx;
val = ((uint64_t)tbl8_idx << 1) | TRIE_EXT_ENT;
}
```
Wait--reviewing the actual patch, the error check IS present at lines 361-362 in the original code, and the patch does not remove it. Re-reading: the patch context shows the error check exists. Let me verify the line numbers against the patch hunks.
Looking at the second hunk (write_edge function):
```c
@@ -359,7 +360,7 @@ write_edge(struct rte_trie_tbl *dp, const uint8_t *ip_part, uint64_t next_hop,
tbl8_idx = tbl8_alloc(dp, val);
if (tbl8_idx < 0)
return tbl8_idx;
- val = (tbl8_idx << 1)|TRIE_EXT_ENT;
+ val = ((uint64_t)tbl8_idx << 1) | TRIE_EXT_ENT;
}
```
The error check is present in the context (unchanged line). So `tbl8_idx` cannot be negative when the shift occurs. The cast to `uint64_t` is still necessary to prevent overflow when `tbl8_idx` has bit 30 set (values >= 2^30).
Actually, that's not an overflow--`tbl8_idx` is `int`, and shifting a non-negative `int` left by 1 is well-defined unless the result exceeds INT_MAX. If `tbl8_idx` is in the range [0, 2^30-1], `tbl8_idx << 1` is in [0, 2^31-2], which fits in a signed 32-bit int. The subsequent implicit conversion to `uint64_t` for the bitwise OR is also defined.
But wait: if `tbl8_idx` is >= 2^30, then `tbl8_idx << 1` would overflow `int` (signed). Let me check the domain of `tbl8_alloc()`. It returns a tbl8 group index, which is bounded by the table size. Without seeing the allocation code, I'll assume it can return values up to 2^24 (the commit message mentions "tbl8 group 0x800001"). If so, `0x800001 << 1 = 0x1000002`, which fits in `uint32_t` but exceeds INT_MAX, causing signed overflow in `int`.
So the cast to `uint64_t` before shift is necessary to avoid signed overflow when `tbl8_idx` is >= 2^30. The patch is correct here.
Re-checking the first location (`build_common_root`): same pattern, same correctness.
No error to report here--the patch fixes the bug correctly.
---
## WARNINGS
None.
---
## INFO
**Correctness**: The patch correctly addresses the sign-extension bug described in the commit message. Making `idx` and `prev_idx` unsigned prevents sign-extension when they are used as array indices. Using a separate signed `tbl8_idx` for the allocation result preserves the ability to check for negative error returns. The casts to `uint64_t` before shifting prevent signed overflow.
**Code review**: The changes are minimal, focused, and follow DPDK style (declaration at start of block, explicit type casts, consistent spacing).
Review-Result: CLEAN
More information about the test-report
mailing list