Add VPP patch 0010: opt-in inner-aware flow hash for IPinIP/GRE/NVGRE#234
Conversation
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
18032d1 to
f2da5f6
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
Will create PR to VPP upstream later |
f2da5f6 to
f2f9182
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
vpp upstream PR: https://gerrit.fd.io/r/c/vpp/+/45864 |
lolyu
left a comment
There was a problem hiding this comment.
📊 Overview
Files Changed: 2 (vppbld/patches/0010-sonic-inner-aware-flow-hash.patch, rename from 0011→0010; vppbld/patches/README.md implied)
Lines: ~1927 in the patch file
VPP core patch implementing the inner-aware flow hash feature: new IP_FLOW_HASH_PEEK_INNER flag, shared ip_inner_aware_hash.h helper, changes to ip4/ip6_compute_flow_hash, hash_eth_l34_inline, VPP unit tests, and RST developer documentation.
✅ Strengths
ip_inner_resolvebounds checking is thorough throughout — every byte access is gated against theremainingcounter, and all failure paths (truncated packet, unknown inner IP version, fragmented inner, unsupported GRE protocol type, unrecognised IPv6 extension header) setinner.valid = 0and let the caller fall back to the outer-only hash. No crash path.- Fragment safety: IPv4 outer fragments correctly skip peeking (
ip4_is_fragmentguard); IPv6 outer fragments setouter_fragmented = 1which blocks thepeek_innerelse-branch via the!outer_fragmentedguard. - IP_FLOW_HASH_DEFAULT unchanged (0x9F) — the new bit is at position 9, cleanly outside all existing defaults. Zero behaviour change for any FIB that does not explicitly request
peek_inner. - ABI preserved: no new
BOND_API_LB_ALGO_*enumerator is introduced;hash-eth-l34is extended in place, so no enum regeneration or CRC bump is needed on the libsaivs side. - 30+ VPP unit tests covering the full tunnel matrix (IPv4/IPv6 outer × IPv4/IPv6 inner, NVGRE, fragmented outer, truncated outer, IPv6 extension-header walk, determinism) plus a perf harness — excellent coverage.
📝 Review Findings
📝 Minor Issues
!PREDICT_FALSE(ip4_is_fragment(ip4)) idiom in hash_eth_l34_inline
if (!PREDICT_FALSE (ip4_is_fragment (ip4)))
{
...
ip_inner_resolve (...);
}The negation of PREDICT_FALSE is semantically correct but idiomatically unusual in VPP. The conventional expression is PREDICT_TRUE(!ip4_is_fragment(ip4)) or simply if (!ip4_is_fragment(ip4)) — both carry the same prediction hint that the non-fragment path is hot. Not a functional issue; purely a style nit.
IPv6 outer in hash_eth_l34_inline does not check for outer fragmentation before calling ip_inner_resolve
For the IPv6 LAG path, ip_inner_resolve is called directly with ip6->protocol without checking whether the outer IPv6 packet is a fragment (NH=44). In practice this is safe — if the outer IPv6 has a fragment extension header as its first next-header, ip6->protocol is 44, and ip_inner_resolve returns valid=0 for that unknown protocol, falling back to the outer hash. However the IPv4 path does explicitly guard with ip4_is_fragment, so the asymmetry is slightly surprising. A comment noting why the IPv6 path omits the explicit guard (i.e., ip_inner_resolve handles NH=44 safely via the fallback) would help future readers.
💡 Suggestions
- The RST developer doc (
inner_aware_hash.rst) and the patch commit message mention SRv6 is not handled, but only implicitly (SRH/NH=43 is not listed in the "walk outer IPv6 extension headers" section). A one-line note in §Testing or the RST doc that SRv6 outer falls back to outer-only hash would complete the exclusion story documented in the accompanying HLD (PR #235).
🧪 Testing
30+ unit test cases covering the full functional matrix, plus a perf harness — this is more coverage than most VPP patches carry. No gaps found.
Status
✅ Approved — clean implementation, thorough safety guards, minor style nit and one documentation suggestion only.
…_INNER algo
This patch makes VPP's IPv4/IPv6 ECMP and bond LAG load-balancers
hash on the inner header of IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE
transit tunnels, so distinct inner flows between the same two tunnel
endpoints distribute across paths and bond members instead of
collapsing onto a single path.
Behaviour is fully opt-in on both surfaces:
* IP layer (ECMP) — a new flow-hash bit IP_FLOW_HASH_PEEK_INNER
(1<<9, CLI keyword 'peek_inner') in flow_hash_config_t.
IP_FLOW_HASH_DEFAULT stays at 0x9F; when the bit is not set,
ip4_compute_flow_hash and ip6_compute_flow_hash behave exactly
as upstream.
* LAG — a NEW load-balance algorithm BOND_API_LB_ALGO_L34_INNER = 6
in src/vnet/bonding/bond.api (CLI keyword 'l34-inner'), backed
by a NEW registered Ethernet hash function 'hash-eth-l34-inner'
(priority 50) in src/vnet/hash/hash_eth.c. The existing
BOND_API_LB_ALGO_L34 (= 1) and 'hash-eth-l34' are byte-for-byte
unchanged, so any LAG that does not explicitly select 'l34-inner'
sees zero behaviour change and zero extra cost. This replaces
the earlier in-place 'always-on with safe fallback' edit of
hash-eth-l34 in response to upstream review (Fred Wang, lolyu).
* ABI compatibility for the new enum value is preserved by the
[backwards_compatible] annotation: vppapigen excludes the new
member from the CRCs of bond_create / bond_create2 /
sw_interface_bond_details / sw_bond_interface_details, so a
libsaivs built without the new value continues to link and run
against a VPP built with it. The same mechanism is used by
enum sr_behavior in src/vnet/srv6/sr_types.api and
enum ipsec_crypto_alg in src/vnet/ipsec/ipsec_types.api.
* A new helper src/vnet/ip/ip_inner_aware_hash.h houses the
inner-peek inlines used identically by all three hash surfaces
(ip4_compute_flow_hash, ip6_compute_flow_hash,
hash_eth_l34_inner). Every entry point takes a u32 'remaining'
bound; outer-fragment packets are skipped; IPv6 inner extension
headers (HBH/DST/ROUTE) are walked, and Fragment / AH / ESP
cause a fall-back to outer-only hashing.
* VxLAN, Geneve and SRv6 are intentionally out of scope. VxLAN
(RFC 7348 §4.2) and Geneve (RFC 8926 §3.3) place inner-flow
entropy in the outer UDP source port; SRv6 (RFC 6437 / RFC
8754 §7) places it in the IPv6 flow label. The existing
outer-only hash already distributes those classes when the
ingress generates the prescribed outer entropy.
* New VPP unit tests (test/test_inner_aware_hash.py) cover the
on/off paths, IPv4/IPv6 outer x IPv4/IPv6 inner, NVGRE,
fragmented outer, truncated outer, IPv6 inner extension
headers, a determinism check, and a regression-safety class
TestLagL34LegacyOuterOnly that pins down that
BOND_API_LB_ALGO_L34 / hash-eth-l34 are byte-for-byte
unchanged after this patch.
* A perf harness (test/test_inner_aware_perf.py) provides three
packet-generator + show-runtime measurement classes: PEEK_INNER
on/off on ECMP, the new L34_INNER LAG algorithm with peek on,
and the legacy L34 LAG algorithm as a side-by-side A/B baseline.
The patch is a single squashed file vppbld/patches/0010-sonic-inner-aware-flow-hash.patch
(2849 lines, 13 files inside VPP, +2326 / -52).
vppbld/patches/series gets a 5-line scope comment listing in-scope
encapsulations (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE),
out-of-scope ones (VxLAN / Geneve / SRv6), and the byte-for-byte
unchanged guarantee for hash-eth-l34 and IP_FLOW_HASH_DEFAULT.
Verified end-to-end on vlab-vpp-01 (vms-kvm-vpp-t1-lag): the full
sonic-mgmt tests/fib/test_fib.py suite is 16/16 PASS (regression
r13), including test_ipinip_hash, test_nvgre_hash and
test_vxlan_hash that were previously skipped on sonic-vpp.
HLD: docs/HLD/vpp-inner-aware-flow-hash.md (branch
inner-aware-flow-hash-hld, separate PR).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Signed-off-by: Jianquan Ye <jianquanye@microsoft.com>
f2f9182 to
c6ace30
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
hi @yejianquan , have you run sonic-mgmt sanity with this change? Please share the test result to make sure no breakage. |
In response to Fred Wang's review (PR sonic-net#234, comment 1 -- "frag fix should hop to outer-only hash"), the inner-aware flow-hash patch 0010 still hit the outer TCP/UDP `tcp->src/dst` read on the non-peek branch even when `outer_fragmented = 1`. On a fragmented IPv6 outer carrying TCP/UDP, the payload after the IPv6 header is not an L4 header at all -- it is a fragment continuation -- so the read returned garbage source/dest ports and the hash diverged from the un-fragmented-first-fragment case. The corresponding fix in upstream VPP (vpp-upstream HEAD, amended into the squashed inner-aware-flow-hash commit) is the 1-line guard `if (!outer_fragmented && ...)` on the non-peek branch in `src/vnet/ip/ip6_inlines.h`, plus an explanatory comment block above it documenting the invariant. Same as the existing peek_inner branch right below it which already had a `!outer_fragmented` guard. The regression test `TestSafetyEdges::test_outer_v6_fragmented_falls_back` in `test/test_inner_aware_hash.py` pins this down: it sends an outer-fragmented IPv6 packet, captures it on the output interface, and asserts the hash equals the hash of the same packet with the fragment header removed (i.e., outer-fragmented and unfragmented forms hash identically because both fall back to outer L3-only). Without the guard the test fails on three forwarding paths (pg1=97 / pg2=73 / pg3=87 packets vs the 64 expected from a balanced fall-back); with the guard all paths converge. Net delta on the patch file: * ip6_inlines.h hunk: +9 net dest-side lines (1 deleted `+if (TCP||UDP)` line -> 10 added lines = comment block + `else if (!outer_fragmented && ...)`) hunk header -66,29 +77,76 -> -66,29 +77,85 * test/test_inner_aware_hash.py hunk: +53 dest-side lines (new method appended before final `if __name__`) hunk header -0,0 +1,1005 -> -0,0 +1,1058 * diff --stat: ip6_inlines.h 84 -> 93, test 1005 -> 1058, grand total +2326 -> +2388 insertions Validated by clean clone of VPP at the pinned commit 435fda042e68ef90734ef5b3530c0a5b911a3bf8 + `git apply` of patches 0001..0010 in series order: exit 0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Jianquan Ye <jianquanye@microsoft.com>
3fea8cb to
05d9791
Compare
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
sonic-mgmt fib/test_fib.py resultsPASS test_basic_fib[True-True-1514]
|
|
Have you created fd.io PR? I think this is a valuable contribution. If it is merged, we don't have to deal with merge conflicts in the future. Please add the fd.io PR to the description. |
|
please resolve the conflicts |
PR sonic-net#238 (no-class-e-drop) merged ahead of this PR and claimed the 0010-* patch-file slot. Rename our patch 0010-sonic-inner-aware-flow-hash.patch -> 0011-sonic-inner-aware-flow-hash.patch and update vppbld/patches/series so that 0010-no-class-e-drop applies first, then 0011-sonic-inner-aware-flow-hash. Also brings in two HLD-only PRs that merged after the previous master merge on this branch (9fa4107): - PR sonic-net#216: docs/HLD/vpp-mirror.md - PR sonic-net#236: docs/HLD/vpp-route-flow-counter.md The two competing patches touch disjoint VPP source trees, so there is no source-level conflict, only the series-file slot collision: - 0010-no-class-e-drop: src/vnet/fib/ip4_fib.{c,h}, test/test_ip4.py - 0011-inner-aware-flow: src/vnet/{bonding,hash,ip}/, test/test_inner_aware_*.py, docs Validated by clean checkout of VPP at the pinned commit 435fda042e68ef90734ef5b3530c0a5b911a3bf8 + `git apply` of all 11 patches in series order: every patch returns exit 0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Jianquan Ye <jianquanye@microsoft.com>
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
Hi @yue-fred-gao , yeah: https://gerrit.fd.io/r/c/vpp/+/45864 all the changes are cherry-picked to the PR. |
PR #234 added vppbld/patches/0011-sonic-inner-aware-flow-hash.patch (introducing BOND_API_LB_ALGO_L34_INNER = 6 and the inner-aware ECMP/LAG hash) but did not bump VPP_VERSION. The vppbld/Makefile keys its cache lookup on VPP_VERSION_SONIC, so downstream sonic-buildimage builds keep pulling the 2026-04-15 0.3+b1sonic1 debs from buildkite -- which were built before patch 0011 existed. As soon as the matching sairedis (PR #1896) lands and starts sending lb=6 to bond_create, the stale VPP rejects the algo, no BondEthernets are created, and all LAG-side BGP sessions stay in Active/Connect (failure visible in sonic-buildimage PR #27621 CI). Bump the minor suffix to 0.4 to invalidate the cache; downstream builds will fall back to build_locally until buildkite is repopulated for 0.4. Add an inline comment documenting the cache-key convention so the next patch contributor does not repeat the miss. Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
PR #234 added vppbld/patches/0011-sonic-inner-aware-flow-hash.patch (introducing BOND_API_LB_ALGO_L34_INNER = 6 and the inner-aware ECMP/LAG hash) but did not bump VPP_VERSION. The vppbld/Makefile keys its cache lookup on VPP_VERSION_SONIC, so downstream sonic-buildimage builds keep pulling the 2026-04-15 0.3+b1sonic1 debs from buildkite -- which were built before patch 0011 existed. As soon as the matching sairedis (PR #1896) lands and starts sending lb=6 to bond_create, the stale VPP rejects the algo, no BondEthernets are created, and all LAG-side BGP sessions stay in Active/Connect (failure visible in sonic-buildimage PR #27621 CI). Bump the minor suffix to 0.4 to invalidate the cache; downstream builds will fall back to build_locally until buildkite is repopulated for 0.4. Add an inline comment documenting the cache-key convention so the next patch contributor does not repeat the miss. vppbld: bump VPP_VERSION 0.3 -> 0.4 to invalidate stale buildkite cache signed-off-by: jianquanye@microsoft.com
…sonic-net#234) * Add VPP patch 0010: opt-in inner-aware flow hash (ECMP) + new LAG L34_INNER algo This patch makes VPP's IPv4/IPv6 ECMP and bond LAG load-balancers hash on the inner header of IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE transit tunnels, so distinct inner flows between the same two tunnel endpoints distribute across paths and bond members instead of collapsing onto a single path. Behaviour is fully opt-in on both surfaces: * IP layer (ECMP) — a new flow-hash bit IP_FLOW_HASH_PEEK_INNER (1<<9, CLI keyword 'peek_inner') in flow_hash_config_t. IP_FLOW_HASH_DEFAULT stays at 0x9F; when the bit is not set, ip4_compute_flow_hash and ip6_compute_flow_hash behave exactly as upstream. * LAG — a NEW load-balance algorithm BOND_API_LB_ALGO_L34_INNER = 6 in src/vnet/bonding/bond.api (CLI keyword 'l34-inner'), backed by a NEW registered Ethernet hash function 'hash-eth-l34-inner' (priority 50) in src/vnet/hash/hash_eth.c. The existing BOND_API_LB_ALGO_L34 (= 1) and 'hash-eth-l34' are byte-for-byte unchanged, so any LAG that does not explicitly select 'l34-inner' sees zero behaviour change and zero extra cost. This replaces the earlier in-place 'always-on with safe fallback' edit of hash-eth-l34 in response to upstream review (Fred Wang, lolyu). * ABI compatibility for the new enum value is preserved by the [backwards_compatible] annotation: vppapigen excludes the new member from the CRCs of bond_create / bond_create2 / sw_interface_bond_details / sw_bond_interface_details, so a libsaivs built without the new value continues to link and run against a VPP built with it. The same mechanism is used by enum sr_behavior in src/vnet/srv6/sr_types.api and enum ipsec_crypto_alg in src/vnet/ipsec/ipsec_types.api. * A new helper src/vnet/ip/ip_inner_aware_hash.h houses the inner-peek inlines used identically by all three hash surfaces (ip4_compute_flow_hash, ip6_compute_flow_hash, hash_eth_l34_inner). Every entry point takes a u32 'remaining' bound; outer-fragment packets are skipped; IPv6 inner extension headers (HBH/DST/ROUTE) are walked, and Fragment / AH / ESP cause a fall-back to outer-only hashing. * VxLAN, Geneve and SRv6 are intentionally out of scope. VxLAN (RFC 7348 §4.2) and Geneve (RFC 8926 §3.3) place inner-flow entropy in the outer UDP source port; SRv6 (RFC 6437 / RFC 8754 §7) places it in the IPv6 flow label. The existing outer-only hash already distributes those classes when the ingress generates the prescribed outer entropy. * New VPP unit tests (test/test_inner_aware_hash.py) cover the on/off paths, IPv4/IPv6 outer x IPv4/IPv6 inner, NVGRE, fragmented outer, truncated outer, IPv6 inner extension headers, a determinism check, and a regression-safety class TestLagL34LegacyOuterOnly that pins down that BOND_API_LB_ALGO_L34 / hash-eth-l34 are byte-for-byte unchanged after this patch. * A perf harness (test/test_inner_aware_perf.py) provides three packet-generator + show-runtime measurement classes: PEEK_INNER on/off on ECMP, the new L34_INNER LAG algorithm with peek on, and the legacy L34 LAG algorithm as a side-by-side A/B baseline. The patch is a single squashed file vppbld/patches/0010-sonic-inner-aware-flow-hash.patch (2849 lines, 13 files inside VPP, +2326 / -52). vppbld/patches/series gets a 5-line scope comment listing in-scope encapsulations (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE), out-of-scope ones (VxLAN / Geneve / SRv6), and the byte-for-byte unchanged guarantee for hash-eth-l34 and IP_FLOW_HASH_DEFAULT. Verified end-to-end on vlab-vpp-01 (vms-kvm-vpp-t1-lag): the full sonic-mgmt tests/fib/test_fib.py suite is 16/16 PASS (regression r13), including test_ipinip_hash, test_nvgre_hash and test_vxlan_hash that were previously skipped on sonic-vpp. HLD: docs/HLD/vpp-inner-aware-flow-hash.md (branch inner-aware-flow-hash-hld, separate PR). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> * patch 0010: fix outer-fragmented IPv6 fall-back in flow hash In response to Fred Wang's review (PR sonic-net#234, comment 1 -- "frag fix should hop to outer-only hash"), the inner-aware flow-hash patch 0010 still hit the outer TCP/UDP `tcp->src/dst` read on the non-peek branch even when `outer_fragmented = 1`. On a fragmented IPv6 outer carrying TCP/UDP, the payload after the IPv6 header is not an L4 header at all -- it is a fragment continuation -- so the read returned garbage source/dest ports and the hash diverged from the un-fragmented-first-fragment case. The corresponding fix in upstream VPP (vpp-upstream HEAD, amended into the squashed inner-aware-flow-hash commit) is the 1-line guard `if (!outer_fragmented && ...)` on the non-peek branch in `src/vnet/ip/ip6_inlines.h`, plus an explanatory comment block above it documenting the invariant. Same as the existing peek_inner branch right below it which already had a `!outer_fragmented` guard. The regression test `TestSafetyEdges::test_outer_v6_fragmented_falls_back` in `test/test_inner_aware_hash.py` pins this down: it sends an outer-fragmented IPv6 packet, captures it on the output interface, and asserts the hash equals the hash of the same packet with the fragment header removed (i.e., outer-fragmented and unfragmented forms hash identically because both fall back to outer L3-only). Without the guard the test fails on three forwarding paths (pg1=97 / pg2=73 / pg3=87 packets vs the 64 expected from a balanced fall-back); with the guard all paths converge. Net delta on the patch file: * ip6_inlines.h hunk: +9 net dest-side lines (1 deleted `+if (TCP||UDP)` line -> 10 added lines = comment block + `else if (!outer_fragmented && ...)`) hunk header -66,29 +77,76 -> -66,29 +77,85 * test/test_inner_aware_hash.py hunk: +53 dest-side lines (new method appended before final `if __name__`) hunk header -0,0 +1,1005 -> -0,0 +1,1058 * diff --stat: ip6_inlines.h 84 -> 93, test 1005 -> 1058, grand total +2326 -> +2388 insertions Validated by clean clone of VPP at the pinned commit 435fda042e68ef90734ef5b3530c0a5b911a3bf8 + `git apply` of patches 0001..0010 in series order: exit 0. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> --------- Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
#24721) ### Description of PR Summary: Re-enable the three previously skipped tunnel-hashing tests for the `vpp` `asic_type` now that VPP has **opt-in** inner-aware ECMP / LAG flow hashing. The two prerequisite changes that make these tests actually pass on `vms-kvm-vpp-t1-lag`: - [sonic-net/sonic-platform-vpp#234](sonic-net/sonic-platform-vpp#234) — vendors VPP patch `0010-sonic-inner-aware-flow-hash.patch`, which registers the **new** opt-in `hash-eth-l34-inner` bond load-balance function, the new `BOND_API_LB_ALGO_L34_INNER = 6` bond algorithm, and the new `FLOW_HASH_PEEK_INNER` ECMP FIB bit. Stock `hash-eth-l34` and the legacy `BOND_API_LB_ALGO_L34 = 1` are byte-for-byte unchanged. - [sonic-net/sonic-sairedis#1896](sonic-net/sonic-sairedis#1896) — opts the `vslib/vpp` adapter into the new path: selects `BOND_API_LB_ALGO_L34_INNER` in `vpp_create_lag` and OR's `VPP_IP_API_FLOW_HASH_PEEK_INNER` into `vpp_add_ip_vrf` for both `AF_INET` and `AF_INET6` (default + non-default VRFs). - `sonic-net/sonic-buildimage` submodule bump for sonic-sairedis is a separate routine PR once #1896 lands. Fixes [#25762](#25762) ### Type of change - [ ] Bug fix - [ ] Testbed and Framework(new/improvement) - [ ] New Test case - [ ] Skipped for non-supported platforms - [x] Test case improvement ### Back port request - [ ] 202205 - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 ### Approach #### What is the motivation for this PR? `fib/test_fib.py::test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` were unconditionally skipped on `asic_type == 'vpp'` because the underlying VPP runtime hashed every transit tunnel (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE) on its **outer** 5-tuple only. When many distinct inner flows share an outer 5-tuple — the common case for SONiC T1-LAG topologies — they collapse onto a single LAG member and a single ECMP next-hop, and these three tests deviate by more than the 5% balance threshold. With the upstream VPP fix (`hash-eth-l34-inner` + `PEEK_INNER` bit) and the libsaivs opt-in landed, the three tests now pass on `vms-kvm-vpp-t1-lag` and there is no reason to keep them on the skip list. #### How did you do it? Two small changes (total **2 files, +12 / −23**): | File | Change | |---|---| | `tests/common/plugins/conditional_mark/tests_mark_conditions_sonic_vpp.yaml` | Remove the three unconditional `skip` entries for `test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` on `asic_type == 'vpp'`. Replace with a comment block that points to issue #25762 and lists the three prerequisites (VPP patch + vslib/vpp opt-in + the `test_nvgre_hash` hash-key override below). | | `tests/fib/test_fib.py` | In `test_nvgre_hash`, add a `vpp` `asic_type` branch that sets `hash_keys = ['src-ip', 'dst-ip', 'src-port', 'dst-port']`. VPP's new opt-in `hash-eth-l34-inner` bond LB peeks into the inner IP/L4 of NVGRE encap but does **not** mix in the inner Ethernet src/dst MAC — identical to the `marvell-teralynx` and `mellanox` behavioural carve-outs already in this test. Without this override, `NvgreHashTest` treats inner MAC variations as additional hash keys and incorrectly flags the run as deviating > 5 %. | #### How did you verify/test it? End-to-end on `vms-kvm-vpp-t1-lag` (`vlab-vpp-01`) with both prerequisite PRs (#234, #1896) applied: ``` cd sonic-mgmt/tests pytest fib/test_fib.py --topology=t1-lag-vpp --testbed=vms-kvm-vpp-t1-lag ``` Result: full `tests/fib/test_fib.py` is **16 / 16 PASS** in 2:01:36 — `test_basic_fib`, `test_hash[ipv4/ipv6]`, `test_ipinip_hash[ipv4/ipv6]`, `test_ipinip_hash_negative[ipv4/ipv6]`, `test_vxlan_hash × 4`, `test_nvgre_hash × 4`, `test_ecmp_group_member_flap`. Re-validated after the `0011 → 0010` VPP patch squash on 2026-05-19. #### Any platform specific information? This PR only affects `asic_type == 'vpp'`: - The `tests_mark_conditions_sonic_vpp.yaml` change is scoped to the `sonic-vpp` conditional-mark file. - The `test_fib.py` change is a new `if duthost.facts['asic_type'] in ["vpp"]:` branch inside `test_nvgre_hash`, parallel to the existing `marvell-teralynx` carve-out. Other `asic_type`s are unaffected. If a sonic-vpp image **without** the two prerequisite changes (PR #234, PR #1896) is used, the three re-enabled tests will deviate > 5 % and fail. This is the expected hard prerequisite — see the comment block in the `tests_mark_conditions_sonic_vpp.yaml` change for details. #### Supported testbed topology if it's a new test case? N/A — this PR re-enables existing tests on an existing topology (`t1-lag-vpp` / `vms-kvm-vpp-t1-lag`). No new test case, no new topology. ### Documentation HLD: [sonic-net/SONiC#1860](sonic-net/SONiC#1860) — *Inner-aware flow hash for VPP-based platforms* (v0.3, opt-in design). --------- Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sonic-net#24721) ### Description of PR Summary: Re-enable the three previously skipped tunnel-hashing tests for the `vpp` `asic_type` now that VPP has **opt-in** inner-aware ECMP / LAG flow hashing. The two prerequisite changes that make these tests actually pass on `vms-kvm-vpp-t1-lag`: - [sonic-net/sonic-platform-vpp#234](sonic-net/sonic-platform-vpp#234) — vendors VPP patch `0010-sonic-inner-aware-flow-hash.patch`, which registers the **new** opt-in `hash-eth-l34-inner` bond load-balance function, the new `BOND_API_LB_ALGO_L34_INNER = 6` bond algorithm, and the new `FLOW_HASH_PEEK_INNER` ECMP FIB bit. Stock `hash-eth-l34` and the legacy `BOND_API_LB_ALGO_L34 = 1` are byte-for-byte unchanged. - [sonic-net/sonic-sairedis#1896](sonic-net/sonic-sairedis#1896) — opts the `vslib/vpp` adapter into the new path: selects `BOND_API_LB_ALGO_L34_INNER` in `vpp_create_lag` and OR's `VPP_IP_API_FLOW_HASH_PEEK_INNER` into `vpp_add_ip_vrf` for both `AF_INET` and `AF_INET6` (default + non-default VRFs). - `sonic-net/sonic-buildimage` submodule bump for sonic-sairedis is a separate routine PR once sonic-net#1896 lands. Fixes [sonic-net#25762](sonic-net#25762) ### Type of change - [ ] Bug fix - [ ] Testbed and Framework(new/improvement) - [ ] New Test case - [ ] Skipped for non-supported platforms - [x] Test case improvement ### Back port request - [ ] 202205 - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 ### Approach #### What is the motivation for this PR? `fib/test_fib.py::test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` were unconditionally skipped on `asic_type == 'vpp'` because the underlying VPP runtime hashed every transit tunnel (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE) on its **outer** 5-tuple only. When many distinct inner flows share an outer 5-tuple — the common case for SONiC T1-LAG topologies — they collapse onto a single LAG member and a single ECMP next-hop, and these three tests deviate by more than the 5% balance threshold. With the upstream VPP fix (`hash-eth-l34-inner` + `PEEK_INNER` bit) and the libsaivs opt-in landed, the three tests now pass on `vms-kvm-vpp-t1-lag` and there is no reason to keep them on the skip list. #### How did you do it? Two small changes (total **2 files, +12 / −23**): | File | Change | |---|---| | `tests/common/plugins/conditional_mark/tests_mark_conditions_sonic_vpp.yaml` | Remove the three unconditional `skip` entries for `test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` on `asic_type == 'vpp'`. Replace with a comment block that points to issue sonic-net#25762 and lists the three prerequisites (VPP patch + vslib/vpp opt-in + the `test_nvgre_hash` hash-key override below). | | `tests/fib/test_fib.py` | In `test_nvgre_hash`, add a `vpp` `asic_type` branch that sets `hash_keys = ['src-ip', 'dst-ip', 'src-port', 'dst-port']`. VPP's new opt-in `hash-eth-l34-inner` bond LB peeks into the inner IP/L4 of NVGRE encap but does **not** mix in the inner Ethernet src/dst MAC — identical to the `marvell-teralynx` and `mellanox` behavioural carve-outs already in this test. Without this override, `NvgreHashTest` treats inner MAC variations as additional hash keys and incorrectly flags the run as deviating > 5 %. | #### How did you verify/test it? End-to-end on `vms-kvm-vpp-t1-lag` (`vlab-vpp-01`) with both prerequisite PRs (sonic-net#234, sonic-net#1896) applied: ``` cd sonic-mgmt/tests pytest fib/test_fib.py --topology=t1-lag-vpp --testbed=vms-kvm-vpp-t1-lag ``` Result: full `tests/fib/test_fib.py` is **16 / 16 PASS** in 2:01:36 — `test_basic_fib`, `test_hash[ipv4/ipv6]`, `test_ipinip_hash[ipv4/ipv6]`, `test_ipinip_hash_negative[ipv4/ipv6]`, `test_vxlan_hash × 4`, `test_nvgre_hash × 4`, `test_ecmp_group_member_flap`. Re-validated after the `0011 → 0010` VPP patch squash on 2026-05-19. #### Any platform specific information? This PR only affects `asic_type == 'vpp'`: - The `tests_mark_conditions_sonic_vpp.yaml` change is scoped to the `sonic-vpp` conditional-mark file. - The `test_fib.py` change is a new `if duthost.facts['asic_type'] in ["vpp"]:` branch inside `test_nvgre_hash`, parallel to the existing `marvell-teralynx` carve-out. Other `asic_type`s are unaffected. If a sonic-vpp image **without** the two prerequisite changes (PR sonic-net#234, PR sonic-net#1896) is used, the three re-enabled tests will deviate > 5 % and fail. This is the expected hard prerequisite — see the comment block in the `tests_mark_conditions_sonic_vpp.yaml` change for details. #### Supported testbed topology if it's a new test case? N/A — this PR re-enables existing tests on an existing topology (`t1-lag-vpp` / `vms-kvm-vpp-t1-lag`). No new test case, no new topology. ### Documentation HLD: [sonic-net/SONiC#1860](sonic-net/SONiC#1860) — *Inner-aware flow hash for VPP-based platforms* (v0.3, opt-in design). --------- Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: selldinesh <dinesh.sellappan@keysight.com>
sonic-net#24721) ### Description of PR Summary: Re-enable the three previously skipped tunnel-hashing tests for the `vpp` `asic_type` now that VPP has **opt-in** inner-aware ECMP / LAG flow hashing. The two prerequisite changes that make these tests actually pass on `vms-kvm-vpp-t1-lag`: - [sonic-net/sonic-platform-vpp#234](sonic-net/sonic-platform-vpp#234) — vendors VPP patch `0010-sonic-inner-aware-flow-hash.patch`, which registers the **new** opt-in `hash-eth-l34-inner` bond load-balance function, the new `BOND_API_LB_ALGO_L34_INNER = 6` bond algorithm, and the new `FLOW_HASH_PEEK_INNER` ECMP FIB bit. Stock `hash-eth-l34` and the legacy `BOND_API_LB_ALGO_L34 = 1` are byte-for-byte unchanged. - [sonic-net/sonic-sairedis#1896](sonic-net/sonic-sairedis#1896) — opts the `vslib/vpp` adapter into the new path: selects `BOND_API_LB_ALGO_L34_INNER` in `vpp_create_lag` and OR's `VPP_IP_API_FLOW_HASH_PEEK_INNER` into `vpp_add_ip_vrf` for both `AF_INET` and `AF_INET6` (default + non-default VRFs). - `sonic-net/sonic-buildimage` submodule bump for sonic-sairedis is a separate routine PR once sonic-net#1896 lands. Fixes [sonic-net#25762](sonic-net#25762) ### Type of change - [ ] Bug fix - [ ] Testbed and Framework(new/improvement) - [ ] New Test case - [ ] Skipped for non-supported platforms - [x] Test case improvement ### Back port request - [ ] 202205 - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 ### Approach #### What is the motivation for this PR? `fib/test_fib.py::test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` were unconditionally skipped on `asic_type == 'vpp'` because the underlying VPP runtime hashed every transit tunnel (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE) on its **outer** 5-tuple only. When many distinct inner flows share an outer 5-tuple — the common case for SONiC T1-LAG topologies — they collapse onto a single LAG member and a single ECMP next-hop, and these three tests deviate by more than the 5% balance threshold. With the upstream VPP fix (`hash-eth-l34-inner` + `PEEK_INNER` bit) and the libsaivs opt-in landed, the three tests now pass on `vms-kvm-vpp-t1-lag` and there is no reason to keep them on the skip list. #### How did you do it? Two small changes (total **2 files, +12 / −23**): | File | Change | |---|---| | `tests/common/plugins/conditional_mark/tests_mark_conditions_sonic_vpp.yaml` | Remove the three unconditional `skip` entries for `test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` on `asic_type == 'vpp'`. Replace with a comment block that points to issue sonic-net#25762 and lists the three prerequisites (VPP patch + vslib/vpp opt-in + the `test_nvgre_hash` hash-key override below). | | `tests/fib/test_fib.py` | In `test_nvgre_hash`, add a `vpp` `asic_type` branch that sets `hash_keys = ['src-ip', 'dst-ip', 'src-port', 'dst-port']`. VPP's new opt-in `hash-eth-l34-inner` bond LB peeks into the inner IP/L4 of NVGRE encap but does **not** mix in the inner Ethernet src/dst MAC — identical to the `marvell-teralynx` and `mellanox` behavioural carve-outs already in this test. Without this override, `NvgreHashTest` treats inner MAC variations as additional hash keys and incorrectly flags the run as deviating > 5 %. | #### How did you verify/test it? End-to-end on `vms-kvm-vpp-t1-lag` (`vlab-vpp-01`) with both prerequisite PRs (sonic-net#234, sonic-net#1896) applied: ``` cd sonic-mgmt/tests pytest fib/test_fib.py --topology=t1-lag-vpp --testbed=vms-kvm-vpp-t1-lag ``` Result: full `tests/fib/test_fib.py` is **16 / 16 PASS** in 2:01:36 — `test_basic_fib`, `test_hash[ipv4/ipv6]`, `test_ipinip_hash[ipv4/ipv6]`, `test_ipinip_hash_negative[ipv4/ipv6]`, `test_vxlan_hash × 4`, `test_nvgre_hash × 4`, `test_ecmp_group_member_flap`. Re-validated after the `0011 → 0010` VPP patch squash on 2026-05-19. #### Any platform specific information? This PR only affects `asic_type == 'vpp'`: - The `tests_mark_conditions_sonic_vpp.yaml` change is scoped to the `sonic-vpp` conditional-mark file. - The `test_fib.py` change is a new `if duthost.facts['asic_type'] in ["vpp"]:` branch inside `test_nvgre_hash`, parallel to the existing `marvell-teralynx` carve-out. Other `asic_type`s are unaffected. If a sonic-vpp image **without** the two prerequisite changes (PR sonic-net#234, PR sonic-net#1896) is used, the three re-enabled tests will deviate > 5 % and fail. This is the expected hard prerequisite — see the comment block in the `tests_mark_conditions_sonic_vpp.yaml` change for details. #### Supported testbed topology if it's a new test case? N/A — this PR re-enables existing tests on an existing topology (`t1-lag-vpp` / `vms-kvm-vpp-t1-lag`). No new test case, no new topology. ### Documentation HLD: [sonic-net/SONiC#1860](sonic-net/SONiC#1860) — *Inner-aware flow hash for VPP-based platforms* (v0.3, opt-in design). --------- Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: selldinesh <dinesh.sellappan@keysight.com>
sonic-net#24721) ### Description of PR Summary: Re-enable the three previously skipped tunnel-hashing tests for the `vpp` `asic_type` now that VPP has **opt-in** inner-aware ECMP / LAG flow hashing. The two prerequisite changes that make these tests actually pass on `vms-kvm-vpp-t1-lag`: - [sonic-net/sonic-platform-vpp#234](sonic-net/sonic-platform-vpp#234) — vendors VPP patch `0010-sonic-inner-aware-flow-hash.patch`, which registers the **new** opt-in `hash-eth-l34-inner` bond load-balance function, the new `BOND_API_LB_ALGO_L34_INNER = 6` bond algorithm, and the new `FLOW_HASH_PEEK_INNER` ECMP FIB bit. Stock `hash-eth-l34` and the legacy `BOND_API_LB_ALGO_L34 = 1` are byte-for-byte unchanged. - [sonic-net/sonic-sairedis#1896](sonic-net/sonic-sairedis#1896) — opts the `vslib/vpp` adapter into the new path: selects `BOND_API_LB_ALGO_L34_INNER` in `vpp_create_lag` and OR's `VPP_IP_API_FLOW_HASH_PEEK_INNER` into `vpp_add_ip_vrf` for both `AF_INET` and `AF_INET6` (default + non-default VRFs). - `sonic-net/sonic-buildimage` submodule bump for sonic-sairedis is a separate routine PR once sonic-net#1896 lands. Fixes [sonic-net#25762](sonic-net#25762) ### Type of change - [ ] Bug fix - [ ] Testbed and Framework(new/improvement) - [ ] New Test case - [ ] Skipped for non-supported platforms - [x] Test case improvement ### Back port request - [ ] 202205 - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 ### Approach #### What is the motivation for this PR? `fib/test_fib.py::test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` were unconditionally skipped on `asic_type == 'vpp'` because the underlying VPP runtime hashed every transit tunnel (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE) on its **outer** 5-tuple only. When many distinct inner flows share an outer 5-tuple — the common case for SONiC T1-LAG topologies — they collapse onto a single LAG member and a single ECMP next-hop, and these three tests deviate by more than the 5% balance threshold. With the upstream VPP fix (`hash-eth-l34-inner` + `PEEK_INNER` bit) and the libsaivs opt-in landed, the three tests now pass on `vms-kvm-vpp-t1-lag` and there is no reason to keep them on the skip list. #### How did you do it? Two small changes (total **2 files, +12 / −23**): | File | Change | |---|---| | `tests/common/plugins/conditional_mark/tests_mark_conditions_sonic_vpp.yaml` | Remove the three unconditional `skip` entries for `test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` on `asic_type == 'vpp'`. Replace with a comment block that points to issue sonic-net#25762 and lists the three prerequisites (VPP patch + vslib/vpp opt-in + the `test_nvgre_hash` hash-key override below). | | `tests/fib/test_fib.py` | In `test_nvgre_hash`, add a `vpp` `asic_type` branch that sets `hash_keys = ['src-ip', 'dst-ip', 'src-port', 'dst-port']`. VPP's new opt-in `hash-eth-l34-inner` bond LB peeks into the inner IP/L4 of NVGRE encap but does **not** mix in the inner Ethernet src/dst MAC — identical to the `marvell-teralynx` and `mellanox` behavioural carve-outs already in this test. Without this override, `NvgreHashTest` treats inner MAC variations as additional hash keys and incorrectly flags the run as deviating > 5 %. | #### How did you verify/test it? End-to-end on `vms-kvm-vpp-t1-lag` (`vlab-vpp-01`) with both prerequisite PRs (sonic-net#234, sonic-net#1896) applied: ``` cd sonic-mgmt/tests pytest fib/test_fib.py --topology=t1-lag-vpp --testbed=vms-kvm-vpp-t1-lag ``` Result: full `tests/fib/test_fib.py` is **16 / 16 PASS** in 2:01:36 — `test_basic_fib`, `test_hash[ipv4/ipv6]`, `test_ipinip_hash[ipv4/ipv6]`, `test_ipinip_hash_negative[ipv4/ipv6]`, `test_vxlan_hash × 4`, `test_nvgre_hash × 4`, `test_ecmp_group_member_flap`. Re-validated after the `0011 → 0010` VPP patch squash on 2026-05-19. #### Any platform specific information? This PR only affects `asic_type == 'vpp'`: - The `tests_mark_conditions_sonic_vpp.yaml` change is scoped to the `sonic-vpp` conditional-mark file. - The `test_fib.py` change is a new `if duthost.facts['asic_type'] in ["vpp"]:` branch inside `test_nvgre_hash`, parallel to the existing `marvell-teralynx` carve-out. Other `asic_type`s are unaffected. If a sonic-vpp image **without** the two prerequisite changes (PR sonic-net#234, PR sonic-net#1896) is used, the three re-enabled tests will deviate > 5 % and fail. This is the expected hard prerequisite — see the comment block in the `tests_mark_conditions_sonic_vpp.yaml` change for details. #### Supported testbed topology if it's a new test case? N/A — this PR re-enables existing tests on an existing topology (`t1-lag-vpp` / `vms-kvm-vpp-t1-lag`). No new test case, no new topology. ### Documentation HLD: [sonic-net/SONiC#1860](sonic-net/SONiC#1860) — *Inner-aware flow hash for VPP-based platforms* (v0.3, opt-in design). --------- Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: selldinesh <dinesh.sellappan@keysight.com>
sonic-net#24721) ### Description of PR Summary: Re-enable the three previously skipped tunnel-hashing tests for the `vpp` `asic_type` now that VPP has **opt-in** inner-aware ECMP / LAG flow hashing. The two prerequisite changes that make these tests actually pass on `vms-kvm-vpp-t1-lag`: - [sonic-net/sonic-platform-vpp#234](sonic-net/sonic-platform-vpp#234) — vendors VPP patch `0010-sonic-inner-aware-flow-hash.patch`, which registers the **new** opt-in `hash-eth-l34-inner` bond load-balance function, the new `BOND_API_LB_ALGO_L34_INNER = 6` bond algorithm, and the new `FLOW_HASH_PEEK_INNER` ECMP FIB bit. Stock `hash-eth-l34` and the legacy `BOND_API_LB_ALGO_L34 = 1` are byte-for-byte unchanged. - [sonic-net/sonic-sairedis#1896](sonic-net/sonic-sairedis#1896) — opts the `vslib/vpp` adapter into the new path: selects `BOND_API_LB_ALGO_L34_INNER` in `vpp_create_lag` and OR's `VPP_IP_API_FLOW_HASH_PEEK_INNER` into `vpp_add_ip_vrf` for both `AF_INET` and `AF_INET6` (default + non-default VRFs). - `sonic-net/sonic-buildimage` submodule bump for sonic-sairedis is a separate routine PR once sonic-net#1896 lands. Fixes [sonic-net#25762](sonic-net#25762) ### Type of change - [ ] Bug fix - [ ] Testbed and Framework(new/improvement) - [ ] New Test case - [ ] Skipped for non-supported platforms - [x] Test case improvement ### Back port request - [ ] 202205 - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 ### Approach #### What is the motivation for this PR? `fib/test_fib.py::test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` were unconditionally skipped on `asic_type == 'vpp'` because the underlying VPP runtime hashed every transit tunnel (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE) on its **outer** 5-tuple only. When many distinct inner flows share an outer 5-tuple — the common case for SONiC T1-LAG topologies — they collapse onto a single LAG member and a single ECMP next-hop, and these three tests deviate by more than the 5% balance threshold. With the upstream VPP fix (`hash-eth-l34-inner` + `PEEK_INNER` bit) and the libsaivs opt-in landed, the three tests now pass on `vms-kvm-vpp-t1-lag` and there is no reason to keep them on the skip list. #### How did you do it? Two small changes (total **2 files, +12 / −23**): | File | Change | |---|---| | `tests/common/plugins/conditional_mark/tests_mark_conditions_sonic_vpp.yaml` | Remove the three unconditional `skip` entries for `test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` on `asic_type == 'vpp'`. Replace with a comment block that points to issue sonic-net#25762 and lists the three prerequisites (VPP patch + vslib/vpp opt-in + the `test_nvgre_hash` hash-key override below). | | `tests/fib/test_fib.py` | In `test_nvgre_hash`, add a `vpp` `asic_type` branch that sets `hash_keys = ['src-ip', 'dst-ip', 'src-port', 'dst-port']`. VPP's new opt-in `hash-eth-l34-inner` bond LB peeks into the inner IP/L4 of NVGRE encap but does **not** mix in the inner Ethernet src/dst MAC — identical to the `marvell-teralynx` and `mellanox` behavioural carve-outs already in this test. Without this override, `NvgreHashTest` treats inner MAC variations as additional hash keys and incorrectly flags the run as deviating > 5 %. | #### How did you verify/test it? End-to-end on `vms-kvm-vpp-t1-lag` (`vlab-vpp-01`) with both prerequisite PRs (sonic-net#234, sonic-net#1896) applied: ``` cd sonic-mgmt/tests pytest fib/test_fib.py --topology=t1-lag-vpp --testbed=vms-kvm-vpp-t1-lag ``` Result: full `tests/fib/test_fib.py` is **16 / 16 PASS** in 2:01:36 — `test_basic_fib`, `test_hash[ipv4/ipv6]`, `test_ipinip_hash[ipv4/ipv6]`, `test_ipinip_hash_negative[ipv4/ipv6]`, `test_vxlan_hash × 4`, `test_nvgre_hash × 4`, `test_ecmp_group_member_flap`. Re-validated after the `0011 → 0010` VPP patch squash on 2026-05-19. #### Any platform specific information? This PR only affects `asic_type == 'vpp'`: - The `tests_mark_conditions_sonic_vpp.yaml` change is scoped to the `sonic-vpp` conditional-mark file. - The `test_fib.py` change is a new `if duthost.facts['asic_type'] in ["vpp"]:` branch inside `test_nvgre_hash`, parallel to the existing `marvell-teralynx` carve-out. Other `asic_type`s are unaffected. If a sonic-vpp image **without** the two prerequisite changes (PR sonic-net#234, PR sonic-net#1896) is used, the three re-enabled tests will deviate > 5 % and fail. This is the expected hard prerequisite — see the comment block in the `tests_mark_conditions_sonic_vpp.yaml` change for details. #### Supported testbed topology if it's a new test case? N/A — this PR re-enables existing tests on an existing topology (`t1-lag-vpp` / `vms-kvm-vpp-t1-lag`). No new test case, no new topology. ### Documentation HLD: [sonic-net/SONiC#1860](sonic-net/SONiC#1860) — *Inner-aware flow hash for VPP-based platforms* (v0.3, opt-in design). --------- Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sonic-net#24721) ### Description of PR Summary: Re-enable the three previously skipped tunnel-hashing tests for the `vpp` `asic_type` now that VPP has **opt-in** inner-aware ECMP / LAG flow hashing. The two prerequisite changes that make these tests actually pass on `vms-kvm-vpp-t1-lag`: - [sonic-net/sonic-platform-vpp#234](sonic-net/sonic-platform-vpp#234) — vendors VPP patch `0010-sonic-inner-aware-flow-hash.patch`, which registers the **new** opt-in `hash-eth-l34-inner` bond load-balance function, the new `BOND_API_LB_ALGO_L34_INNER = 6` bond algorithm, and the new `FLOW_HASH_PEEK_INNER` ECMP FIB bit. Stock `hash-eth-l34` and the legacy `BOND_API_LB_ALGO_L34 = 1` are byte-for-byte unchanged. - [sonic-net/sonic-sairedis#1896](sonic-net/sonic-sairedis#1896) — opts the `vslib/vpp` adapter into the new path: selects `BOND_API_LB_ALGO_L34_INNER` in `vpp_create_lag` and OR's `VPP_IP_API_FLOW_HASH_PEEK_INNER` into `vpp_add_ip_vrf` for both `AF_INET` and `AF_INET6` (default + non-default VRFs). - `sonic-net/sonic-buildimage` submodule bump for sonic-sairedis is a separate routine PR once sonic-net#1896 lands. Fixes [sonic-net#25762](sonic-net#25762) ### Type of change - [ ] Bug fix - [ ] Testbed and Framework(new/improvement) - [ ] New Test case - [ ] Skipped for non-supported platforms - [x] Test case improvement ### Back port request - [ ] 202205 - [ ] 202305 - [ ] 202311 - [ ] 202405 - [ ] 202411 - [ ] 202505 - [ ] 202511 ### Approach #### What is the motivation for this PR? `fib/test_fib.py::test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` were unconditionally skipped on `asic_type == 'vpp'` because the underlying VPP runtime hashed every transit tunnel (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE) on its **outer** 5-tuple only. When many distinct inner flows share an outer 5-tuple — the common case for SONiC T1-LAG topologies — they collapse onto a single LAG member and a single ECMP next-hop, and these three tests deviate by more than the 5% balance threshold. With the upstream VPP fix (`hash-eth-l34-inner` + `PEEK_INNER` bit) and the libsaivs opt-in landed, the three tests now pass on `vms-kvm-vpp-t1-lag` and there is no reason to keep them on the skip list. #### How did you do it? Two small changes (total **2 files, +12 / −23**): | File | Change | |---|---| | `tests/common/plugins/conditional_mark/tests_mark_conditions_sonic_vpp.yaml` | Remove the three unconditional `skip` entries for `test_ipinip_hash`, `test_nvgre_hash`, and `test_vxlan_hash` on `asic_type == 'vpp'`. Replace with a comment block that points to issue sonic-net#25762 and lists the three prerequisites (VPP patch + vslib/vpp opt-in + the `test_nvgre_hash` hash-key override below). | | `tests/fib/test_fib.py` | In `test_nvgre_hash`, add a `vpp` `asic_type` branch that sets `hash_keys = ['src-ip', 'dst-ip', 'src-port', 'dst-port']`. VPP's new opt-in `hash-eth-l34-inner` bond LB peeks into the inner IP/L4 of NVGRE encap but does **not** mix in the inner Ethernet src/dst MAC — identical to the `marvell-teralynx` and `mellanox` behavioural carve-outs already in this test. Without this override, `NvgreHashTest` treats inner MAC variations as additional hash keys and incorrectly flags the run as deviating > 5 %. | #### How did you verify/test it? End-to-end on `vms-kvm-vpp-t1-lag` (`vlab-vpp-01`) with both prerequisite PRs (sonic-net#234, sonic-net#1896) applied: ``` cd sonic-mgmt/tests pytest fib/test_fib.py --topology=t1-lag-vpp --testbed=vms-kvm-vpp-t1-lag ``` Result: full `tests/fib/test_fib.py` is **16 / 16 PASS** in 2:01:36 — `test_basic_fib`, `test_hash[ipv4/ipv6]`, `test_ipinip_hash[ipv4/ipv6]`, `test_ipinip_hash_negative[ipv4/ipv6]`, `test_vxlan_hash × 4`, `test_nvgre_hash × 4`, `test_ecmp_group_member_flap`. Re-validated after the `0011 → 0010` VPP patch squash on 2026-05-19. #### Any platform specific information? This PR only affects `asic_type == 'vpp'`: - The `tests_mark_conditions_sonic_vpp.yaml` change is scoped to the `sonic-vpp` conditional-mark file. - The `test_fib.py` change is a new `if duthost.facts['asic_type'] in ["vpp"]:` branch inside `test_nvgre_hash`, parallel to the existing `marvell-teralynx` carve-out. Other `asic_type`s are unaffected. If a sonic-vpp image **without** the two prerequisite changes (PR sonic-net#234, PR sonic-net#1896) is used, the three re-enabled tests will deviate > 5 % and fail. This is the expected hard prerequisite — see the comment block in the `tests_mark_conditions_sonic_vpp.yaml` change for details. #### Supported testbed topology if it's a new test case? N/A — this PR re-enables existing tests on an existing topology (`t1-lag-vpp` / `vms-kvm-vpp-t1-lag`). No new test case, no new topology. ### Documentation HLD: [sonic-net/SONiC#1860](sonic-net/SONiC#1860) — *Inner-aware flow hash for VPP-based platforms* (v0.3, opt-in design). --------- Signed-off-by: Jianquan Ye <jianquanye@microsoft.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: selldinesh <dinesh.sellappan@keysight.com>
Why
Support vpp inner packet hash compute aware for sonic-net/sonic-buildimage#25762
This patch makes VPP's IPv4/IPv6 ECMP and bond LAG load-balancers hash on the inner header of IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE transit tunnels, so distinct inner flows between the same two tunnel endpoints distribute across paths and bond members instead of collapsing onto asingle path.
Design
Behaviour is fully opt-in on both surfaces:
IP layer (ECMP) — a new flow-hash bit
IP_FLOW_HASH_PEEK_INNER(1<<9, CLI keywordpeek_inner) inflow_hash_config_t.IP_FLOW_HASH_DEFAULTstays at0x9F; when the bit is not set,ip4_compute_flow_hashandip6_compute_flow_hashbehave exactly as upstream.LAG — a new load-balance algorithm
BOND_API_LB_ALGO_L34_INNER = 6insrc/vnet/bonding/bond.api(CLI keywordl34-inner), backed by a new registered Ethernet hash functionhash-eth-l34-inner(priority 50) insrc/vnet/hash/hash_eth.c. The existingBOND_API_LB_ALGO_L34 = 1andhash-eth-l34are byte-for-byte unchanged, so any LAG that does not explicitly selectl34-innersees zero behaviour change and zero extra cost. This replaces the earlier in-place "always-on with safe fallback" edit ofhash-eth-l34in response toupstream review (Fred Wang, lolyu).ABI compatibility for the new enum value is preserved by the
[backwards_compatible]annotation:vppapigenexcludes the new member from the CRCs ofbond_create/bond_create2/sw_interface_bond_details/sw_bond_interface_details, so a libsaivs built without the newvalue continues to link and run against a VPP built with it. The same mechanism is used byenum sr_behaviorinsrc/vnet/srv6/sr_types.apiandenum ipsec_crypto_alginsrc/vnet/ipsec/ipsec_types.api.Shared helper —
src/vnet/ip/ip_inner_aware_hash.hhouses the inner-peek inlines used identically by all three hash surfaces (ip4_compute_flow_hash,ip6_compute_flow_hash,hash_eth_l34_inner). Every entry point takes au32 remainingbound; outer-fragment packets areskipped; IPv6 inner extension headers (HBH/DST/ROUTE) are walked, and Fragment / AH / ESP cause a fall-back to outer-only hashing.Out of scope — VxLAN (RFC 7348 §4.2) and Geneve (RFC 8926 §3.3) place inner-flow entropy in the outer UDP source port; SRv6 (RFC 6437 / RFC 8754 §7) places it in the IPv6 flow label. The existing outer-only hash already distributes those classes when the ingress generates theprescribed outer entropy.
Test coverage
Unit tests —
test/test_inner_aware_hash.pycovers IPv4/IPv6 outer × IPv4/IPv6 inner, NVGRE, fragmented outer, truncated outer, IPv6 inner extension headers, a determinism check, and a regression-safety classTestLagL34LegacyOuterOnlythat pins down thatBOND_API_LB_ALGO_L34/hash-eth-l34are byte-for-byte unchanged after this patch.Perf harness —
test/test_inner_aware_perf.pyprovides three packet-generator +show runtimemeasurement classes:PEEK_INNERon/off on ECMP, the newL34_INNERLAG algorithm with peek on, and the legacyL34LAG algorithm as a side-by-side A/B baseline.What this PR changes in this repo
vppbld/patches/0010-sonic-inner-aware-flow-hash.patch(new, 2849 lines, 13 files inside VPP, +2326 / -52)vppbld/patches/series— adds the new patch with a 5-line scope comment listing in-scope encapsulations (IPinIP / 6in4 / 4in6 / 6in6 / GRE / NVGRE), out-of-scope ones (VxLAN / Geneve / SRv6), and the byte-for-byte-unchanged guarantee.How to verify
Full
sonic-mgmttests/fib/test_fib.pysuite onvms-kvm-vpp-t1-lag(regression r13):test_basic_fib,test_hash[ipv4]/[ipv6],test_ecmp_group_member_flaptest_ipinip_hash[ipv4]/[ipv6]test_nvgre_hash[ipv4-*]/[ipv6-*]test_vxlan_hash[ipv4-*]/[ipv6-*]test_ipinip_hash_negative[ipv4]/[ipv6]Result: 16 passed, 698 warnings, 2 errors in 7264.48s (2:01:04) — the 2 errors are syncd-shutdown teardown analyzer matches unrelated to flow hashing (they occur with or without this patch).
Companion changes (separate PRs)
docs/HLD/vpp-inner-aware-flow-hash.mdon branchinner-aware-flow-hash-hldvpp_create_lag()selectslb = VPP_BOND_API_LB_ALGO_L34_INNER(6);vpp_add_ip_vrf()ORsVPP_IP_API_FLOW_HASH_PEEK_INNERinto the default-VRF hash mask and adds theAF_INET6 vpp_ip_flow_hash_setcalltest_ipinip_hash/test_nvgre_hash/test_vxlan_hashfrom thevppplatform skip-list; adds avppasic_typebranch fortest_nvgre_hashhash_keysvpp upstream PR: https://gerrit.fd.io/r/c/vpp/+/45864