Match BGP discover afi exactly so ipv4 does not hit vpnv4.

Apply the same global peer-group member expand to address-family ipv4; keep VRF direct-only. Cover IPv4 wrapped neighbor routes.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
oliver 2026-09-22 15:15:27 +08:00
parent 0aa2bcbbe6
commit 6b35add5a4
3 changed files with 38 additions and 2 deletions

View file

@ -137,7 +137,12 @@ def _record_passes_discover_filter(rec: dict[str, Any], ph: PlaceholderDef) -> b
filt_contains = str(ph.discover_filter_contains or "").strip().lower()
if filt_field and filt_contains:
hay = str(rec.get(filt_field) or "").strip().lower()
if filt_contains not in hay:
# ``afi`` must be exact (``ipv4`` must not match ``vpnv4``).
# CSV fields like ``address_families`` still use substring/token contains.
if filt_field == "afi":
if hay != filt_contains:
return False
elif filt_contains not in hay:
return False
require = str(ph.discover_require_nonempty or "").strip()
if require and not str(rec.get(require) or "").strip():

View file

@ -78,6 +78,9 @@ router bgp 65000
neighbor 10.0.0.1 route-map RM_OUT out
neighbor CORE_RR activate
$
address-family ipv4
neighbor CORE_RR activate
$
address-family ipv4 vrf CUST_A
neighbor 10.0.0.2 remote-as 65003
neighbor 10.0.0.2 activate
@ -304,6 +307,10 @@ class ZteConfigIntentTests(unittest.TestCase):
self.assertEqual(by[("vpnv4", "", "10.0.0.9", "CORE_RR")]["remote_as"], "65019")
self.assertEqual(by[("vpnv4", "", "10.0.0.9", "CORE_RR")]["activate"], "enable")
self.assertEqual(by[("ipv4", "CUST_A", "10.0.0.2", "")]["remote_as"], "65003")
# Global ipv4 AF: same peer-group expand as vpnv4 (not VRF)
self.assertIn(("ipv4", "", "", "CORE_RR"), by)
self.assertIn(("ipv4", "", "10.0.0.1", "CORE_RR"), by)
self.assertIn(("ipv4", "", "10.0.0.9", "CORE_RR"), by)
# VRF must not pick up global peer-group members
self.assertNotIn(("ipv4", "CUST_A", "10.0.0.9", "CORE_RR"), by)
self.assertNotIn(("ipv4", "CUST_A", "10.0.0.1", "CORE_RR"), by)

View file

@ -774,9 +774,16 @@ $
filter_discover_records(peer_recs, glob_v6.placeholders[0]),
["FC00::1"],
)
# afi filter is exact: ipv4 must not match vpnv4
vrf_nei = get_profile("zte.bgp_vpnv4_vrf_neighbor_in")
assert vrf_nei is not None
ipv4_nei_ph = next(ph for ph in vrf_nei.placeholders if ph.name == "neighbor")
self.assertEqual(ipv4_nei_ph.discover_filter_contains, "ipv4")
self.assertEqual(
filter_discover_records(peer_recs, ipv4_nei_ph),
["10.0.0.2"],
)
shared = shared_discover_placeholders(vrf_nei)
self.assertEqual(len(shared), 2)
self.assertTrue(all(ph.discover_profile_id == "zte.config_bgp_peer" for ph in shared))
@ -919,6 +926,23 @@ gei-0/0/0/2 is up, ifindex: 2
self.assertEqual(routes[0]["afi"], "vpnv6")
self.assertEqual(routes[0]["direction"], "in")
# IPv4 neighbor routes: same wrap join as vpnv6
v4_wrap = normalize_bgp_route(
raw_text="""
Routes Learned From This Neighbor:
Network Next Hop Metric LocPrf RtPrf Path
* 10.1.0.0/24
10.0.0.1
20 65001 ?
""",
command="show bgp ipv4 unicast neighbor in 10.0.0.1",
params={"neighbor": "10.0.0.1", "direction": "in", "afi": "ipv4"},
)
self.assertEqual(len(v4_wrap), 1)
self.assertEqual(v4_wrap[0]["network"], "10.1.0.0/24")
self.assertEqual(v4_wrap[0]["next_hop"], "10.0.0.1")
self.assertEqual(v4_wrap[0]["afi"], "ipv4")
if __name__ == "__main__":
unittest.main()