Add L3VNI cross-DC test cases (L3VNI_dci:1-2, 6-30, 39-43, 91, 101) + 6 trigger classes#12
Add L3VNI cross-DC test cases (L3VNI_dci:1-2, 6-30, 39-43, 91, 101) + 6 trigger classes#12bpar9 wants to merge 102 commits into
Conversation
- Add test_base_dci_l3vni_ipv4_across_dci: L3VNI IPv4 traffic across DCI - Add test_base_dci_l3vni_ipv6_across_dci: L3VNI IPv6 traffic across DCI - Add test_base_dci_l3vni_control_plane_across_dci: L3VNI control plane verification (VRF-VNI maps, EVPN VNI, BGP EVPN summary, Type-5 routes) - Add verify_evpn_type5_routes_dci() helper in vxlan_helper.py - Enable ENABLE_L3_ACROSS_DCI flag for cross-DC L3 stream generation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
- L3VNI_dci:1: Full base profile verification (VRF-VNI, VLAN-VNI, Type-5 routes on BGWs) + IPv4 traffic across DCI - L3VNI_dci:2: Type-5 route detail verification (format, L3VNI in ext-community, IPv6 VTEP next-hop, RT values) + BGP EVPN summary + IPv6 traffic across DCI - L3VNI_dci:6: eBGP multihop EVPN session verification between BGWs across DCs + VRF-VNI maps + EVPN VNI table + Type-5 route exchange New helpers in vxlan_helper.py: - verify_evpn_type5_route_detail_dci(): Checks Type-5 route format, L3VNI (10101/10102) in extended community, RT values, IPv6 next-hop - verify_bgp_evpn_multihop_sessions_dci(): Verifies eBGP multihop EVPN sessions to remote DC BGWs via OVERLAY_WAN peer-group
…plan - Rename test_base_dci_l3vni_ipv4_across_dci -> test_base_dci_l3vni_base_profile (L3VNI_dci:1) - Rename test_base_dci_l3vni_ipv6_across_dci -> test_base_dci_l3vni_type5_route_ipv6_vtep (L3VNI_dci:2) - Rename test_base_dci_l3vni_control_plane_across_dci -> test_base_dci_l3vni_ebgp_multihop_bgw (L3VNI_dci:6) - Remove config steps 1-3 from L3VNI_dci:1 docstring (config done by hooks, not test code) - Remove traffic step from L3VNI_dci:1 (not in testplan description) - Remove BGP EVPN summary step and traffic step from L3VNI_dci:2 (not in testplan description) - Update docstrings to match testplan titles exactly
|
In the l3vni_config_diff.txt file we have configuration specific to L3VNI which is missing here. This needs to incorporated before doing testcases verification. |
1 similar comment
|
In the l3vni_config_diff.txt file we have configuration specific to L3VNI which is missing here. This needs to incorporated before doing testcases verification. |
…rification Incorporates the L3VNI-specific configuration for all BGW nodes as part of the config_bgw_nodes() fixture, ensuring it runs before L3VNI test verification. SONiC CLI (l3vni_sonic_bgw_dci): - VLAN 101/102 creation, VRF add, VRF-VLAN bindings - VXLAN map on vxlan-dc and vxlan-wan (cross-DC L3VNI 10101/10102) - VRF-VNI map (Vrf101->10101, Vrf102->10102) FRR config (l3vni_frr_bgw_dci): - VRF-VNI bindings (cross-DC L3VNI) - BGP extcommunity-lists (RT-WAN-* for leaf routes, RT-DC-* for remote BGW routes) - RT-REWRITE-WAN route-map (IPv4 WAN VIP next-hop) - RT-REWRITE-DC route-map (IPv6 DC VIP next-hop) - Apply route-maps to OVERLAY and OVERLAY_WAN neighbors - BGP VRF config with route-target import/export Helper functions added to vxlan_helper.py: - _get_l3vni_bgw_params(): Computes per-BGW L3VNI parameters from topology - generate_l3vni_bgw_sonic_config(): SONiC CLI config generator - generate_l3vni_bgw_frr_config(): FRR config generator - delete_l3vni_bgw_frr_config(): FRR unconfig generator Addresses PR comment about missing L3VNI configuration from l3vni_config_diff.txt.
|
Addressed: L3VNI configuration from The L3VNI-specific configuration is now applied as part of Two new config features added:
All parameters derived dynamically from topology data. Corresponding |
|
there is additional configuartions in L3VNI_config_diff.txt file specific to L3VNI which is missing here. This needs to incorporated before doing testcases verification. |
Per l3vni_config_diff.txt lines 1-39, each leaf node needs to import route-targets from its local (same-DC) BGW cross-DC L3VNI so that Type-5 prefix routes from remote DCs are accepted into the leaf's VRF. Example for DC1 leafs (Vrf101, cross-DC VNI 10101): route-target import 65102:10101 (DC1 BGW1) route-target import 65103:10101 (DC1 BGW2) Changes: - vxlan_helper.py: Add generate_l3vni_leaf_rt_config() and delete_l3vni_leaf_rt_config() helpers; register l3vni_leaf_rt_dci and delete_l3vni_leaf_rt_dci features in config_feature_dci() - test_vxlan_dci.py: Apply l3vni_leaf_rt_dci in config_l2l3vni() after bgp_l3vni_config_dci; remove in unconfig_l2l3vni() before delete_bgp_l3vni_config_dci
|
@bpar9 Addressed the missing L3VNI configurations from BGW config (commit cba3b5f) — lines 42-685 of
Leaf VRF route-target imports (commit 75434ec) — lines 1-39 of
All parameters derived dynamically from topology data. Cross-DC VNI computed as |
|
For the verification, we have this verify_base_setup_bgw in the test_vxlan_dci.py file. Can we use that function to verify L3VNI base testcases? |
…VNI checks Per PR review comment: replace manual VRF-VNI and VLAN-VNI verification loops in L3VNI test cases with calls to verify_base_setup_bgw(). - L3VNI_dci:1: Steps 1-2 (VRF-VNI + VLAN-VNI on all nodes) replaced with verify_base_setup_bgw(nodes, checks=['vrf_vni', 'vlan_vni']) - L3VNI_dci:2: Step 2 (VRF-VNI on BGWs) replaced with verify_base_setup_bgw(bgw_nodes, checks=['vrf_vni']) - L3VNI_dci:6: Step 2 (VRF-VNI on BGWs) replaced with verify_base_setup_bgw(bgw_nodes, checks=['vrf_vni']) - Type-5 route verification remains custom (not available in verify_base_setup_bgw)
|
@vallabh78 Good suggestion. Refactored in commit 8349da3 to reuse
The Type-5 route verification (Steps 2/3 in L3VNI_dci:1, Step 1 in L3VNI_dci:2) and eBGP multihop session verification (Step 1 in L3VNI_dci:6) remain as custom code since |
|
can we move the evpn route type 5 verification to verify_base_setup_bgw and call it in the testcase? In that way we can use it in other testcases. |
|
We need to add this bgp cache: bgp_info = vxlan_obj.get_bgp_underlay_info_cached() and pass it into l3vni_sonic_bgw_dci and l3vni_frr_bgw_dci in the config_bgw_nodes function. Without this it caused the script to fail and script was unable to configure any BGP related config. |
…config_bgw_nodes Address PR review comments: 1. Move EVPN Type-5 route verification into verify_base_setup_bgw as a new 'evpn_type5' check (BGW-only, auto-skipped on leaf nodes). Added to ALL_CHECKS, control_plane CHECK_SET, and docstring. 2. Add bgp_info = vxlan_obj.get_bgp_underlay_info_cached() in config_bgw_nodes and pass it to l3vni_sonic_bgw_dci and l3vni_frr_bgw_dci calls to fix BGP config lookup failures. Refactored L3VNI test cases to use new evpn_type5 check: - L3VNI_dci:1: checks=['vrf_vni', 'vlan_vni', 'evpn_type5'] - L3VNI_dci:2: checks=['vrf_vni', 'evpn_type5'] (Step 2) - L3VNI_dci:6: checks=['vrf_vni', 'evpn_type5'] (merged old Steps 2+4)
|
@vallabh78 Done in commit fbe972b. Added
All 3 L3VNI test cases now use it:
The detailed Type-5 route verification ( |
|
@vallabh78 Fixed in commit fbe972b. Added bgp_info = vxlan_obj.get_bgp_underlay_info_cached()
vxlan_obj.config_feature_parallel(bgw_nodes, 'l3vni_sonic_bgw_dci', dci_enabled=True, bgp_info=bgp_info)
vxlan_obj.config_feature_parallel(bgw_nodes, 'l3vni_frr_bgw_dci', dci_enabled=True, bgp_info=bgp_info) |
|
Lets follow the same pattern for all testcases and use verify_base_setup_bgw and call specific verification based on testcase requirement. |
…t pattern Add three new reusable checks to verify_base_setup_bgw: - evpn_type5_detail: Detailed Type-5 route verification (format, L3VNI, RT, IPv6 next-hop) - ebgp_multihop: eBGP multihop EVPN session verification between BGWs across DCs - evpn_vni: EVPN VNI table verification (L3 VNIs on BGW nodes) Refactor L3VNI_dci:2 and L3VNI_dci:6 to use verify_base_setup_bgw for all verification instead of custom loops, following the same pattern as L3VNI_dci:1. L3VNI_dci:2: checks=['evpn_type5_detail', 'vrf_vni', 'evpn_type5'] L3VNI_dci:6: checks=['ebgp_multihop', 'vrf_vni', 'evpn_type5', 'evpn_vni']
|
@vallabh78 Done in commit 9d286a7. All three L3VNI test cases now follow the same pattern — every verification goes through Three new reusable checks added to
Refactored test cases:
No more custom verification loops in any L3VNI test case. |
|
can we add the L3VNI vlan vrf binding in the vxlan_dci_input_file.yaml for the BGW's? beliw is an example |
|
@vallabh78 Done in commit 401dc90. Added
All BGWs have the same Also updated |
|
So all BGW's use. Update it in the yaml file vrf Vrf101 |
|
Fix this for tc - test_base_dci_l3vni_type5_route_withdrawal
Error: Vlan11 can not be removed. First remove IP addresses assigned to this VLAN and unbind vrf
` |
…AN delete Root cause: The test's fallback path called vlan_obj.delete_vlan() which fails with 'First remove IP addresses assigned to this VLAN and unbind vrf' because VLAN 11 has SVI IPs and VRF bindings. Fix: - When vlan_config cache doesn't have VLAN members, query the DUT directly via vlan_obj.get_vlan_member() using 'show vlan config' - Remove the delete_vlan/create_vlan fallback entirely — only use delete_vlan_member/add_vlan_member which is safe regardless of SVI/VRF state - Fail early if no VLAN member can be found from either source
|
Two bug fixes pushed in commits 224df7d and 9189da9: 1. TGenFail crash fix (dci:8/dci:9) — commit 224df7d Root cause: The spytest TG wrapper internally calls Fix: Consolidated 5 separate 2. VLAN deletion failure fix (dci:30) — commit 9189da9 Root cause: When Fix:
Note: Neither fix modifies any shared code in |
|
still the tc 8 and 9 are failing. |
… ixia_eval
Root cause (from prefix_issue.txt analysis):
The spytest TG wrapper's tg_emulation_bgp_route_config pre-processing
(tg.py lines 2162-2195) intercepts every route config call and:
1. Calls stop_all_protocols
2. Polls protocol_info in a 29-iteration loop looking for the BGP port
3. If the port is NOT found, calls apply_on_the_fly_changes and loops
In our DCI topology the IXIA BGP port (e.g. 1/2/3) is NOT present in
the protocol_info global_per_port response because the new BGP
topology/device-group has no started sessions yet. The wrapper loops
for ~48 minutes calling apply_on_the_fly_changes each iteration until
the IXIA API crashes with:
TG API Fatal Exception: unmatched '}' (<string>, line 1)
Fix: Call ixia_eval('emulation_bgp_route_config', ...) directly to
bypass the wrapper's stop_all_protocols + protocol_info polling.
Manually handle protocol stop/start around the direct API call.
For IPv4: pass 'prefix_from' (prefix length in bits) instead of
'netmask' since the wrapper's netmask-to-prefix_from conversion
is also bypassed.
Fix for dci:8/dci:9 IXIA BGP prefix advertisement failure (commit 51c1f4a)Root cause (from prefix_issue.txt analysis)The spytest TG wrapper's
In our DCI topology, the IXIA BGP port (e.g. This is why consolidating to a single FixBoth The manual protocol lifecycle is:
For IPv4: the wrapper normally converts |
|
test_base_dci_l2l3vni_ipv4_within_dc - this covers test_base_dci_l3vni_sh_ipv4_within_dc and test_base_dci_l3vni_mh_ipv4_within_dc check these testcases and consolidate. We dont want different testcases testing same thing. Also when you consolidate add a print statemenet in the end saying this passes all these testcaeses. YOu can mention the testname and the id |
… tests Per reviewer feedback: the existing L2L3VNI/L2VNI traffic tests already send both L2 and L3 (SH+MH) traffic, making the separate L3VNI SH/MH tests redundant. Removed 8 separate test methods: - test_base_dci_l3vni_sh_ipv4_within_dc (L3VNI_dci:18) - test_base_dci_l3vni_sh_ipv4_across_dci (L3VNI_dci:19) - test_base_dci_l3vni_sh_ipv6_within_dc (L3VNI_dci:20) - test_base_dci_l3vni_sh_ipv6_across_dci (L3VNI_dci:21) - test_base_dci_l3vni_mh_ipv4_within_dc (L3VNI_dci:22) - test_base_dci_l3vni_mh_ipv4_across_dci (L3VNI_dci:23) - test_base_dci_l3vni_mh_ipv6_within_dc (L3VNI_dci:24) - test_base_dci_l3vni_mh_ipv6_across_dci (L3VNI_dci:25) Added print statements to 4 existing tests listing covered testcase IDs: - test_base_dci_l2l3vni_ipv4_within_dc: covers dci:3, dci:13, dci:18, dci:22 - test_base_dci_l2l3vni_ipv6_within_dc: covers dci:4, dci:13, dci:20, dci:24 - test_base_dci_l2vni_ipv4_across_dci: covers dci:5, dci:14, dci:19, dci:23 - test_base_dci_l2vni_ipv6_across_dci: covers dci:6, dci:15, dci:21, dci:25
|
@vallabh78 Done — consolidated in commit ff28be9. Removed 8 redundant test methods (L3VNI_dci:18-25) since the existing L2L3VNI/L2VNI tests already send both L2 and L3 traffic (SH+MH) in a single run:
Each of these 4 tests now prints the full list of covered testcase names and IDs at the end of execution via |
Remove these lines as the testcase prints the same thing L3VNI SH/MH test cases (dci:18-25) have been consolidated into the |
|
Removed the consolidation comment block in commit 8bace49 per your feedback. The |
|
Also modify the name test_base_dci_l2vni_ipv4_across_dci and test_base_dci_l2vni_ipv6_across_dci with l2l3vni for both as we are testing both of them
|
Renamed test_base_dci_l2vni_ipv4_across_dci -> test_base_dci_l2l3vni_ipv4_across_dci Renamed test_base_dci_l2vni_ipv6_across_dci -> test_base_dci_l2l3vni_ipv6_across_dci These tests verify both L2VNI and L3VNI traffic, so the name should reflect that.
|
Renamed in commit c7b870d:
All references (method name, tc_id string, st.log coverage lines) updated. |
|
test_base_dci_bringup - this covers test_base_dci_frr_sonic_cli. If yes, lets consolidate and print the testcase id of test_base_dci_frr_sonic_cli. In the base config testcase, i see few issues:
check all the outputs from available data and fix these issues |
…onsolidate bringup+frr_sonic_cli
1. get_expected_bgp_summary_dci(): Added IPv4 Unicast verification for BGW
underlay TRANSIT_WAN peers (remote-DC BGWs via point-to-point /24 links)
2. get_expected_bgp_l2vpn_evpn_summary_dci(): Extended to return L2VPN EVPN
neighbors for leaf nodes (same-DC leafs + BGW spines via overlay IPv6),
not just BGW nodes. Uses generate_bgp_overlay_info() for correct peers.
3. verify_ipv6_route_dci(): New helper to verify IPv6 routes via
'show ipv6 route vrf all' — checks connected + BGP routes present.
Added 'ipv6_route' check to ALL_CHECKS and verify_base_setup_bgw.
4. Consolidated test_base_dci_frr_sonic_cli into test_base_dci_bringup:
- Single test now covers Solution_dci:1, Solution_dci:2, L3VNI_dci:1,
L3VNI_dci:2
- Step 1: comprehensive verification on all nodes (ALL_CHECKS)
- Step 2: leaf-specific Type-5 + VRF-VNI checks (L3VNI_dci:2)
- st.log() statements document all covered test IDs
|
can we parameterize tc 26,27,28,29? make sure we print clear statements which tc's were covered in each |
…feedback
1. Solution_dci:3/4/5/6 (L2L3VNI traffic tests): Consolidated 4 separate
test methods into single parameterized test_base_dci_l2l3vni_traffic()
with @pytest.mark.parametrize('ip_version,scope', [...]).
Parameters: (v4/v6) x (within/cross) = 4 combinations.
2. L3VNI_dci:26/27/28/29 (dual-stack tests): Consolidated 4 separate
test methods into single parameterized test_base_dci_l3vni_dualstack_traffic()
with @pytest.mark.parametrize('host_type,scope', [...]).
Parameters: (SH/MH) x (within/cross) = 4 combinations.
Both use test_map dict pattern (matching test_dci_link_trigger style) to
map parameters to tc_id, test case numbers, and traffic config. Each prints
clear st.log() statements documenting which test IDs are covered.
|
@vallabh78 Done in commit 4ce72ec. Both groups are now parameterized: Solution_dci:3,4,5,6 → single @pytest.mark.parametrize("ip_version,scope", [
("v4", "within"), # Solution_dci:3 + L3VNI_dci:13
("v6", "within"), # Solution_dci:4 + L3VNI_dci:13
("v4", "cross"), # Solution_dci:5 + L3VNI_dci:14
("v6", "cross"), # Solution_dci:6 + L3VNI_dci:15
])L3VNI_dci:26,27,28,29 → single @pytest.mark.parametrize("host_type,scope", [
("SH", "within"), # L3VNI_dci:26
("SH", "cross"), # L3VNI_dci:27
("MH", "within"), # L3VNI_dci:28
("MH", "cross"), # L3VNI_dci:29
])Both use |
|
For the TestVxlanInterfaceTriggers class, lets use the code from this file. this file has continuous traffic which we want for these testcases. We should have both l2 and l3 continuous traffic so if L3 is missing add that. |
… traffic and EVPN type-2 withdrawal checks - Replace lazy _create_dci_fc_streams with eager continuous stream creation in tgen_preconfig - Add L3 continuous cross-DC traffic (IPv4+IPv6) alongside L2 for DCI link flap/shut tests - Add EVPN Type-2 withdrawal verification helpers from reviewer's code: _yaml_member_matches_host_port, _host_info_keys_for_portchannel, _collect_hosts_on_leaf_interfaces, _type2_withdrawn_on_remote, _verify_remote_type2_withdrawn_dc2_dc3 - test_leaf_interface_shut_noshut: verify EVPN type-2 withdrawn on DC2/DC3 after shut - test_dci_link_trigger: use eager dci_flap_continuous (L2+L3), skip burst baseline when continuous available, TC29 uses burst only per reviewer's pattern - All L3VNI_dci references maintained in test_map and banners
|
Integrated reviewer's Changes:
|
|
Can we print all the indivisual prefixes advertised by IXIA BGP peer? not just one. and once all type 5 verification done print type5 verification successfull. same for ipv4 testcase Vlan deletion is not working as well |
…pology Issue 1: IXIA prefix logging (dci:8/dci:9) - Expand num_routes into individual prefix strings before verification (e.g. 2001:db8::/64 with num_routes=5 becomes 5 separate prefixes) - Print each individual prefix found in verification output - Add 'IXIA Type-5 verification successful' message Issue 2: Route withdrawal verification (dci:30) - In multi-DC topology, removing a VLAN member on one leaf does NOT make the prefix disappear on BGW nodes (remote DC routes remain) - Changed from prefix-absence check to path-count-decrease verification - Record path counts before removal, verify they decrease after removal - IP route withdrawal check now logs warning instead of failing when remote DC paths keep the route present - Added get_type5_path_counts_dci() helper in vxlan_helper.py
|
Both issues addressed in commit 4c289e3: Issue 1 — IXIA prefix logging (dci:8/dci:9):
Issue 2 — Route withdrawal verification (dci:30):
|
|
test_leaf_interface_shut_noshut - add l3_v4 and v6 traffic for these testcases |
Are we correclty deleting the vlan interface. We have to remove the vlan members, remove the vrf binding, remove the IP address of vlan and then delete. Once the test is done add all this back |
…VLAN deletion in dci:30 1. test_leaf_interface_shut_noshut: Added l3_v4 and l3_v6 traffic types to all verify_traffic() calls (pre-check and post-recovery for both PortChannel and orphan interface flaps). 2. L3VNI_dci:30 (test_base_dci_l3vni_type5_route_withdrawal): Rewritten to perform full VLAN deletion sequence instead of just member remove/add: - Deletion: remove members → disable SAG → unbind VRF → remove IPs → delete VLAN - Restoration: create VLAN → add IPs → enable SAG → bind VRF → add members - VLAN 11 config: Vrf101, 11.11.11.1/24, 11:11:11::1/64, SAG enabled - Exception handler performs full restoration on failure
|
@vallabh78 Both comments addressed in commit 7eaf65b: Comment 1 — L3 traffic in
Traffic types are now Comment 2 — Full VLAN deletion in dci:30: Deletion (Step 2):
Restoration (Step 4):
Exception handler also performs full restoration to ensure cleanup on failure. |
Description of PR
Summary:
Adds cross-DC L3VNI test automation for VXLAN DCI across a 3-datacenter EVPN-VXLAN fabric topology. Changes span two files:
test_vxlan_dci.py(test cases) andvxlan_helper.py(helper functions).Test cases added in
test_vxlan_dci.py:test_base_dci_l3vni_base_profile) — VRF-VNI, VLAN-VNI maps on all leaf+BGW nodestest_base_dci_l3vni_type5_route_ipv6_vtep) — Type-5 route detail with IPv6 VTEP next-hoptest_base_dci_l3vni_ebgp_multihop_bgw) — eBGP multihop EVPN between BGWstest_base_dci_l3vni_rt_translation) — RT-REWRITE route-map verification on BGW nodestest_base_dci_l3vni_type5_ipv6_prefix_advertisement) — IXIA BGP IPv6 prefix advertisement + Type-5 verificationtest_base_dci_l3vni_type5_ipv4_prefix_advertisement) — IXIA BGP IPv4 prefix advertisement + Type-5 verificationtest_base_dci_l2l3vni_traffic(ip_version, scope)— single method covers all 4 combinationstest_base_dci_l3vni_dualstack_traffic(host_type, scope)— single method covers all 4 combinationsHelpers added in
vxlan_helper.py:generate_l3vni_bgw_sonic_config()/generate_l3vni_bgw_frr_config()— BGW L3VNI config froml3vni_config_diff.txtgenerate_l3vni_leaf_rt_config()— Leaf VRF route-target importsverify_evpn_type5_comprehensive()— Unified Type-5 route verification (single reusable check)verify_ipv6_route_dci()— IPv6 route verification viashow ipv6 route vrf all(checks connected + BGP routes)configure_ixia_bgp_ipv4/ipv6_session()— IXIA BGP peer setup + prefix advertisementconfigure_dut_ixia_l3_intf()/remove_dut_ixia_l3_intf()— DUT-side VLAN/SVI/VRF for IXIA peer (supports IPv4-only, IPv6-only, or dual-stack)configure_dut_bgp_for_ixia()/remove_dut_bgp_for_ixia()— DUT-side BGP neighbor config (supports IPv4-only, IPv6-only, or dual-stack)verify_dut_bgp_ixia_session()— Verify BGP Established + routes received from IXIA (supports IPv4-only, IPv6-only, or dual-stack)verify_bgp_evpn_multihop_sessions_dci()— eBGP multihop session verificationverify_ip_route_vrf_dci()— Verify IP route presence/absence in VRF for specific VLANsverify_type5_ixia_prefixes_dci()— Verify specific IXIA-advertised prefixes in Type-5 route outputget_type5_path_counts_dci()— Get per-prefix path counts for Type-5 routes (used for multi-DC withdrawal verification)Updates since last revision
Commit 4c289e3 (fix IXIA prefix expansion and multi-DC route withdrawal verification per reviewer feedback):
Issue 1 - IXIA prefix logging (dci:8/dci:9): Fixed IXIA BGP prefix verification to expand
num_routesparameter into individual prefix strings before passing to verification helper:ipv6_prefixes/ipv4_prefixeswithnum_routes=5, but only passed the base prefix string (e.g.'2001:db8::/64') to verification instead of expanding to all 5 prefixes (e.g.['2001:db8::/64', '2001:db8:1::/64', ...])ipaddressmodule to generate consecutive network addresses from base prefix andnum_routesparameterverify_type5_ixia_prefixes_dci()to print each individual prefix found (indented per-prefix log) and add final success message with prefix countIssue 2 - Route withdrawal verification (dci:30): Fixed Type-5 route withdrawal verification to handle multi-DC topology correctly:
get_type5_path_counts_dci()helperget_type5_path_counts_dci()invxlan_helper.py(lines 8413-8456) — parses Type-5 detailed output and returns per-prefix path counts dictCommit 58712e7 (integrate reviewer's TestVxlanInterfaceTriggers with continuous L2+L3 traffic and EVPN type-2 withdrawal checks):
Eager continuous traffic creation — Changed from lazy/on-demand pattern back to eager creation in
tgen_preconfig():l3_cross_dc_endpoints(missing from reviewer's code)stream_handles['dci_flap_continuous']for reuse bytest_dci_link_triggerdci_enabledflag (derived from topologytest_cfg['nodes'].get('l2l3vni_bgw')) to avoid creating streams when BGW nodes are absentEVPN Type-2 withdrawal verification — New helper methods from reviewer's attached file:
_yaml_member_matches_host_port()— Match TGEN key (e.g.T1D3P1) to yaml shorthand (e.g.T1P1)_host_info_keys_for_portchannel()— Resolve PortChannel to host_info keys usingport_vlan_dict_collect_hosts_on_leaf_interfaces()— Collect MAC/IP fromg_v4/g_v6_host_info_dictfor given interfaces_type2_withdrawn_on_remote()— Poll remote leaf for Type-2 route withdrawal (8 retries, 2s interval, fast first 5)_verify_remote_type2_withdrawn_dc2_dc3()— Check all DC2/DC3 leafs for Type-2 withdrawalTestVxlanInterfaceTriggers updates:
test_leaf_interface_shut_noshut: Added Step 2b to verify EVPN Type-2 withdrawn on DC2/DC3 leafs after interface shut (both orphan and PortChannel)test_dci_link_trigger: Uses eagerdci_flap_continuousdict (no_create_dci_fc_streamscall), TC 29 uses burst only (no continuous), min_perc=99.6 check after trigger, skip burst recovery when using continuousverify_traffic()calls now include L3 traffic types ('l3_v4','l3_v6')IPv6 route verification — Added
ipv6_routecheck toALL_CHECKSandverify_base_setup_bgw()(callsverify_ipv6_route_dci())Commit 80380eb (base config test fixes: IPv4/L2VPN BGP checks + ipv6 route + test consolidation):
IPv4 Unicast BGP verification for BGW underlay:
get_expected_bgp_summary_dci()now returns IPv4 Unicast neighbors for BGW nodes — verifies TRANSIT_WAN peer-group (point-to-point /24 links to remote-DC BGWs). Previously only returned IPv6 Unicast neighbors.L2VPN EVPN BGP verification for leaf nodes:
get_expected_bgp_l2vpn_evpn_summary_dci()now returns L2VPN EVPN neighbors for both BGW and leaf nodes. Usesgenerate_bgp_overlay_info()to get correct same-DC leaf + BGW spine peers for leaf nodes. Previously only handled BGW nodes.IPv6 route verification: New
verify_ipv6_route_dci()helper verifies IPv6 routes viashow ipv6 route vrf all— checks for connected routes (loopback/SVI) and BGP-learned routes. Addedipv6_routecheck toALL_CHECKSandverify_base_setup_bgw(). Raises exception if no routes found, logs statistics about route types.Test consolidation: Merged
test_base_dci_frr_sonic_cliintotest_base_dci_bringup— single test now covers Solution_dci:1+2 and L3VNI_dci:1+2. Two-step approach:checks='all')st.log()statements document all 4 covered test IDsCommit 4ce72ec (parameterize Solution_dci:3-6 and L3VNI_dci:26-29):
Solution_dci:3/4/5/6 parameterization: Consolidated 4 separate L2L3VNI traffic test methods into single
test_base_dci_l2l3vni_traffic(ip_version, scope)with@pytest.mark.parametrize("ip_version,scope", [("v4", "within"), ("v6", "within"), ("v4", "cross"), ("v6", "cross")]). Usestest_mapdict to map parameters to tc_id, test case numbers, traffic types, and covered test IDs. Prints clearst.log()statements showing all covered testcase IDs per run.L3VNI_dci:26/27/28/29 parameterization: Consolidated 4 separate dual-stack test methods into single
test_base_dci_l3vni_dualstack_traffic(host_type, scope)with@pytest.mark.parametrize("host_type,scope", [("SH", "within"), ("SH", "cross"), ("MH", "within"), ("MH", "cross")]). Usestest_mapdict pattern matchingtest_dci_link_triggerstyle.Commit ff28be9 (consolidate L3VNI SH/MH test cases per reviewer feedback):
Test case consolidation: Removed 8 separate L3VNI SH/MH test methods (dci:18-25) because the existing L2L3VNI/L2VNI traffic tests already send both L2 and L3 (SH+MH) traffic in a single run:
test_base_dci_l2l3vni_ipv4_within_dcnow covers: Solution_dci:3, L3VNI_dci:13, L3VNI_dci:18 (SH), L3VNI_dci:22 (MH)test_base_dci_l2l3vni_ipv6_within_dcnow covers: Solution_dci:4, L3VNI_dci:13, L3VNI_dci:20 (SH), L3VNI_dci:24 (MH)test_base_dci_l2vni_ipv4_across_dcinow covers: Solution_dci:5, L3VNI_dci:14, L3VNI_dci:19 (SH), L3VNI_dci:23 (MH)test_base_dci_l2vni_ipv6_across_dcinow covers: Solution_dci:6, L3VNI_dci:15, L3VNI_dci:21 (SH), L3VNI_dci:25 (MH)Documentation added: Each of the 4 consolidated tests now prints the full list of covered testcase names and IDs at the end via
st.log()statements.Removed tests: Deleted 8 redundant test methods (lines 5885-6183 in test_vxlan_dci.py) and replaced with consolidation comment explaining the mapping.
Commit e7ffeb8 (fixing
verify_vtep()TypeError):dci_enabled=Falseparameter toverify_vtep()andget_expected_remote_vteps()dci_enabled=True,get_expected_remote_vteps()also includes the local DC's BGW VIP (e.g.4000:1::1) in each leaf's expected remote VTEP list viagenerate_dci_vip_maps()TypeError: verify_vtep() got an unexpected keyword argument 'dci_enabled'that occurred in trigger test classesCommit 2c6163b (addressing reviewer feedback):
config vlan member add 99 <interface>. DUT interface resolved from TGEN port name (T1D5P3→D5T1P3→Ethernet224).verify_dut_bgp_ixia_session()helper verifies BGP session is Established and expected routes are received from IXIA before Type-5 verification on BGW nodes.evpn_type5_comprehensivecheck (no changes needed).Commit fe70cb5 (L3VNI_dci:30 rewrite + IXIA prefix verification for dci:8-9):
L3VNI_dci:30 (Type-5 route withdrawal test) — Rewritten to use VLAN member remove/add pattern:
vlan_obj.delete_vlan_member()/vlan_obj.add_vlan_member()(followstest_remove_add_vlan_memberspattern)L3VNI_dci:8-9 (IXIA prefix advertisement tests) — Added specific IXIA prefix Type-5 verification:
2001:db8::/64through2001:db8:4::/64(expected=new IPv6 routes, actual=present)10.100.0.0/24through10.100.4.0/24(expected=new IPv4 routes, actual=present)verify_type5_ixia_prefixes_dci()helper withpoll_waitfor convergence handling (30s timeout)New helpers in
vxlan_helper.py:verify_ip_route_vrf_dci(): checks IP route presence/absence in VRF for specific VLANs (used by dci:30)verify_type5_ixia_prefixes_dci(): checks specific prefix strings in Type-5 route output with configurable expect_present flag (used by dci:8-9 and dci:30)Commit 9f19abb (L3VNI_dci:8 IPv6-only fix):
L3VNI_dci:8 (IPv6 prefix test) — Fixed to use IPv6-only BGP neighbor configuration (not dual-stack):
ixia_ip,ixia_gateway,ixia_netmask) from test2099::1/64on Vlan99 (no IPv480.99.0.1)neighbor 2099::100 remote-as 65299underaddress-family ipv6 unicast(no IPv4 neighbor)configure_ixia_bgp_ipv6_session()Helper functions updated for IPv4-only/IPv6-only/dual-stack support:
configure_dut_ixia_l3_intf:svi_ipparameter made optional (defaultNone) to support IPv6-only modeconfigure_dut_bgp_for_ixia:ixia_ipparameter made optional (defaultNone) to support IPv6-only moderemove_dut_ixia_l3_intf:svi_ipparameter made optional (defaultNone)remove_dut_bgp_for_ixia:ixia_ipparameter made optional (defaultNone)L3VNI_dci:9 (IPv4 prefix test) — Already IPv4-only, no changes needed
Commit 34fa8c3 (IXIA BGP helper IPv6-only fixes):
configure_ixia_bgp_ipv6_session()— Reordered parameters and made IPv4 params optional:src_mac,ixia_asn,leaf_asn,ipv6_prefixesare now required positional (positions 3-6)ixia_ip,gateway,netmaskmoved to optional kwargs (defaultNone)ixia_ipisNone(IPv6-only mode)topology_handleis provided but IPv4 params areNone, only IPv6 stack is created on the ethernet layerverify_dut_bgp_ixia_session()— Madeixia_ipoptional:ixia_ipparameter is now optional (defaultNone) to support IPv6-only verificationixia_ipv6whenixia_ipisNoneFixes CRITICAL risk: These changes resolve the potential
TypeErrorwhen L3VNI_dci:8 calls these functions in IPv6-only mode without providingixia_ip.Commit 11599fc (fix dci:8/dci:9 per reviewer feedback):
Issue 1 - Missing BGP config (eBGP policy blocking): Added
no bgp ebgp-requires-policycommand toconfigure_dut_bgp_for_ixia()invxlan_helper.py(line 8956, inside VRF router bgp block, before neighbor configuration). This disables SONiC's default eBGP route blocking behavior so IXIA-advertised routes are accepted without requiring explicit route-map policies on the neighbor.Issue 2 - Slow IXIA prefix installation timing: Added timing instrumentation (
time.time()) around IXIA BGP session configuration in dci:8 (lines 5415, 5441-5442) and dci:9 (lines 5660, 5684-5685). Added documentation comment (lines 5410-5412 in dci:8, 5656-5658 in dci:9) explaining that the slow timing (~3 min per prefix group, ~15 min for 5 prefixes) is expected behavior because the spytest TG wrapper internally stops/starts all protocols for eachtg_emulation_bgp_route_configcall. This is framework-level behavior, not a bug.Issue 3 - Duplicate Type-5 output: Removed the comprehensive Type-5 check (
verify_base_setup_bgw(checks=['evpn_type5_comprehensive'])) from Step 5 of both dci:8 and dci:9. Tests now only callverify_type5_ixia_prefixes_dci()to verify the specific IXIA-advertised prefixes as Type-5 routes on each BGW node. This eliminates duplicate Type-5 output printing (previously printed once by comprehensive check, then again by IXIA-specific check).Commit 224df7d (TGenFail crash fix for dci:8/dci:9 — partial fix):
Root cause: Repeated protocol stop/start cycles from calling
tg_emulation_bgp_route_config5 separate times (once per prefix group) corrupted the TG API port handle state, causingTGenFail: Failed to get port 1/2/3 from the protocol infoafter ~22 minutes.Fix: Consolidated 5 separate
tg_emulation_bgp_route_configcalls into 1 call withnum_routes=5andprefix_step=1in bothconfigure_ixia_bgp_ipv4_session()andconfigure_ixia_bgp_ipv6_session():configure_ixia_bgp_ipv4_session(): Changed from 5 calls (one per prefix) to single call withnum_routes=5,prefix='10.100.0.0',prefix_step=1(lines 8801-8841)configure_ixia_bgp_ipv6_session(): Changed from 5 calls (one per prefix) to single call withnum_routes=5,prefix='2001:db8::',prefix_step=1(lines 8594-8624)Test case changes: Updated L3VNI_dci:8 and L3VNI_dci:9 prefix definitions from 5 separate dict entries to single consolidated prefix range
NOTE: This consolidation fix was incomplete — the tests still failed with the same symptoms. The actual root cause and complete fix is in commit 51c1f4a below.
Commit 9189da9 (dci:30 VLAN deletion fix):
Root cause: When
vlan_configcache didn't have VLAN member info, test fell back tovlan_obj.delete_vlan()which fails with'First remove IP addresses assigned to this VLAN and unbind vrf'because VLAN 11 has SVI IPs and VRF bindings.Fix: Dynamic VLAN member discovery + eliminate delete_vlan fallback:
vlan_configdoesn't have VLAN members for target leaf/VLAN, query DUT directly viavlan_obj.get_vlan_member(target_leaf, vlan_list=[target_vlan])usingshow vlan configelsebranches that attempteddelete_vlan()/create_vlan()— always usedelete_vlan_member()/add_vlan_member()pattern (safe regardless of SVI/VRF state)Changes in
test_base_dci_l3vni_type5_route_withdrawal()(lines 6352-6460):elsebranchelsebranchelsebranchCommit 51c1f4a (COMPLETE fix for dci:8/dci:9 IXIA BGP route advertisement failure):
Root cause (from prefix_issue.txt analysis): The spytest TG wrapper's
tg_emulation_bgp_route_configpre-processing (tg.pylines 2162-2195) intercepts every route config call and:stop_all_protocols(line 2171)protocol_infoin a 29-iteration loop (lines 2178-2191) looking for the BGP port handle in theglobal_per_portresponseapply_on_the_fly_changesand continues looping1/2/3) is NOT present in theprotocol_inforesponse because the new BGP topology/device-group has no started sessions yetapply_on_the_fly_changeseach iteration until the IXIA API crashes with:TG API Fatal Exception: unmatched '}' (<string>, line 1)Fix: Both
configure_ixia_bgp_ipv6_session()andconfigure_ixia_bgp_ipv4_session()now calltg_handle.ixia_eval('emulation_bgp_route_config', ...)directly to bypass the wrapper'sstop_all_protocols+protocol_infopolling entirely:stop_all_protocols+ 15s sleep →ixia_eval('emulation_bgp_route_config', ...)→apply_on_the_fly_changes+ 5s wait →start_all_protocols+ 30s waitnetmask→prefix_from(prefix length in bits). Since we bypass the wrapper, we passprefix_fromdirectly instead ofnetmaskChanges in
vxlan_helper.py:configure_ixia_bgp_ipv6_session()(lines 8594-8660): Replacedtg_emulation_bgp_route_config()with manual stop →ixia_eval()→ apply → start sequenceconfigure_ixia_bgp_ipv4_session()(lines 8837-8906): Same pattern, plus usesprefix_frominstead ofnetmaskType of change
Back port request
Approach
What is the motivation for this PR?
Provide test automation for cross-DC L3VNI functionality in VXLAN DCI deployments using BGW (Border Gateway) nodes with RT-REWRITE route-maps for inter-DC traffic. This enables verification of:
How did you do it?
config_bgw_nodes()applies SONiC CLI (VLAN 101/102, VRF, VRF-VNI map) and FRR config (RT-REWRITE-WAN/RT-REWRITE-DC route-maps, VRF route-target import/export) froml3vni_config_diff.txtto all BGW nodes before test verification.config_l2l3vni()applies route-target imports from local BGWs to leaf nodes for cross-DC L3VNI routes.verify_evpn_type5_comprehensive()parsesshow bgp l2vpn evpn route type 5output and checks route presence, RT/ET values, RMAC, IPv6 next-hop, RIB/FIB installation, local/remote class paths — single unified check for all Type-5 verifications.configure_dut_bgp_for_ixia()disablesbgp ebgp-requires-policyto accept IXIA eBGP routes without explicit route-map policies. TGenFail fix (commits 224df7d + 51c1f4a): Consolidated IXIA BGP route config from 5 separate calls to 1 call withnum_routes=5, then bypassed spytest TG wrapper's problematicprotocol_infopolling by callingixia_eval('emulation_bgp_route_config', ...)directly with manual protocol stop/start lifecycle. IXIA prefix expansion fix (commit 4c289e3): Expandednum_routesparameter into individual prefix strings usingipaddressmodule before passing to verification helper, and enhanced logging to print each individual prefix found.@pytest.mark.parametrizefor cleaner code and better test discovery.tgen_preconfig()for both L2 (VLANs 12, 18) and L3 (all cross-DC endpoints) withtransmit_mode='continuous'. Stored instream_handles['dci_flap_continuous']dict for reuse bytest_dci_link_trigger. TC 29 uses burst BUM/L2 only (not continuous); TC 26/28/30 use continuous streams withmin_perc=99.6check. EVPN Type-2 withdrawal verification added via polling helpers (_type2_withdrawn_on_remote,_verify_remote_type2_withdrawn_dc2_dc3) for interface shut tests.verify_vtep()now acceptsdci_enabledparameter to include BGW DC VIPs in expected remote VTEP lists for trigger tests.vlan_obj.get_vlan_member()whenvlan_configdoesn't have members; eliminateddelete_vlan()fallback that fails due to SVI/VRF bindings. Multi-DC route withdrawal fix (commit 4c289e3): Changed from prefix-absence check to path-count-decrease verification using newget_type5_path_counts_dci()helper to handle multi-DC topology where remote DC routes remain after local VLAN member removal.verify_ipv6_route_dci(). Consolidatedtest_base_dci_frr_sonic_cliintotest_base_dci_bringupto eliminate redundant test coverage.dci_enabled=True(derived fromtest_cfg['nodes'].get('l2l3vni_bgw')) to avoid creating UNAPPLIED streams in non-DCI testbeds.How did you verify/test it?
Code-level verification:
python3 -m py_compile)assign_reviewerpassed, Semgrep/Analyze skipped as expectedExpected lab testing:
pytest test_vxlan_dci.py::TestVxlanDCIBase::test_base_dci_*on 3-DC testbedTestVxlanReloadTriggers,TestVxlanInterfaceTriggers) withdci_enabled=TrueRisk factors for reviewer:
get_type5_path_counts_dci()helper parses Type-5 detailed output using_parse_type5_routes_detailed()which is fragile across SONiC/FRR versions. IP route withdrawal check now logs warning instead of failing when remote DC paths persist — could mask real issues.ipaddressmodule to generate consecutive network addresses from base prefix andnum_routes— assumes sequential allocation matches actual IXIA behavior withprefix_step=1. If IXIA allocates prefixes differently, verification will fail._type2_withdrawn_on_remote) with hardcoded timeouts (8 retries, 2s interval, fast first 5 at 1s). May not be sufficient for large topologies or slow convergence. Regex matching in_yaml_member_matches_host_portis fragile across testbed variations.min_perc=99.6for continuous stream checking intest_dci_link_triggermay be too strict (leading to false failures) or too loose (missing real packet loss). Needs lab tuning.tgen_preconfig(). May create UNAPPLIED traffic items for non-DCI tests or tests that don't use continuous streams. Gated ondci_enabledflag to mitigate this.dci_enabled = bool(test_cfg['nodes'].get('l2l3vni_bgw'))assumes BGW nodes are present when DCI is enabled. If topology data is incomplete or structured differently, this detection may fail.traffic_types=['l2_v4', 'l3_v4']withouttraffic_namesfilter, which should include both SH and MH flows. Need to verify in lab that dci:18-25 test cases are actually covered by the consolidated tests.verify_ipv6_route_dci()uses regex pattern matching on raw CLI output (show ipv6 route vrf all), which is fragile across SONiC versions. Patternr'^C[>\s*]'for connected routes andr'^B[>\s*]'for BGP routes may not match all output formats.test_base_dci_bringupnow covers 4 test IDs (Solution_dci:1+2, L3VNI_dci:1+2). Need to verify in lab that all verification steps from the original separate tests are still executed.get_expected_bgp_summary_dci()now returns IPv4 Unicast neighbors for BGW nodes (TRANSIT_WAN peer-group), andget_expected_bgp_l2vpn_evpn_summary_dci()now handles leaf nodes. Both rely on topology data structures being correctly populated. Need lab verification that all expected neighbors are returned.T1D5P3→D5T1P3→Ethernet224) uses regex pattern that may not cover all testbed variations. Ifdut_intfisNone, VLAN member assignment is silently skipped (logged as WARNING).verify_dut_bgp_ixia_session()assumes specific key names in spytest parser output ('neighbor','neighbourip','state','bgpstatus'). Actual parser format may differ.get_expected_remote_vteps(dci_enabled=True)usesre.search(r'_(dc\d+)', node1)to extract DC identifier from node names. If node naming doesn't follow*_dc<N>pattern, this will fail or produce incorrect results.configure_ixia_bgp_ipv6_session()andconfigure_ixia_bgp_ipv4_session()bypass the spytest TG wrapper and calltg_handle.ixia_eval()directly. This is an unsupported code path that may break if the IXIA API changes. The manual protocol lifecycle (stop → configure → apply → start) is hardcoded with specific wait times (15s, 5s, 30s) that may not be sufficient for all testbeds.dci_enabled=True. If the DCI detection logic is incorrect or if some tests expect L3 traffic even without BGW nodes, those tests will fail with missing stream handles.Link to Devin Session: https://cisco-demo.devinenterprise.com/sessions/8fabef50d24246fd9573c19e56e512c6
Requested by: @bpar9