mirror of
https://github.com/hansjone/netx.git
synced 2026-10-11 06:50:49 +08:00
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:
parent
0aa2bcbbe6
commit
6b35add5a4
3 changed files with 38 additions and 2 deletions
|
|
@ -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()
|
filt_contains = str(ph.discover_filter_contains or "").strip().lower()
|
||||||
if filt_field and filt_contains:
|
if filt_field and filt_contains:
|
||||||
hay = str(rec.get(filt_field) or "").strip().lower()
|
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
|
return False
|
||||||
require = str(ph.discover_require_nonempty or "").strip()
|
require = str(ph.discover_require_nonempty or "").strip()
|
||||||
if require and not str(rec.get(require) or "").strip():
|
if require and not str(rec.get(require) or "").strip():
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,9 @@ router bgp 65000
|
||||||
neighbor 10.0.0.1 route-map RM_OUT out
|
neighbor 10.0.0.1 route-map RM_OUT out
|
||||||
neighbor CORE_RR activate
|
neighbor CORE_RR activate
|
||||||
$
|
$
|
||||||
|
address-family ipv4
|
||||||
|
neighbor CORE_RR activate
|
||||||
|
$
|
||||||
address-family ipv4 vrf CUST_A
|
address-family ipv4 vrf CUST_A
|
||||||
neighbor 10.0.0.2 remote-as 65003
|
neighbor 10.0.0.2 remote-as 65003
|
||||||
neighbor 10.0.0.2 activate
|
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")]["remote_as"], "65019")
|
||||||
self.assertEqual(by[("vpnv4", "", "10.0.0.9", "CORE_RR")]["activate"], "enable")
|
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")
|
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
|
# 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.9", "CORE_RR"), by)
|
||||||
self.assertNotIn(("ipv4", "CUST_A", "10.0.0.1", "CORE_RR"), by)
|
self.assertNotIn(("ipv4", "CUST_A", "10.0.0.1", "CORE_RR"), by)
|
||||||
|
|
|
||||||
|
|
@ -774,9 +774,16 @@ $
|
||||||
filter_discover_records(peer_recs, glob_v6.placeholders[0]),
|
filter_discover_records(peer_recs, glob_v6.placeholders[0]),
|
||||||
["FC00::1"],
|
["FC00::1"],
|
||||||
)
|
)
|
||||||
|
# afi filter is exact: ipv4 must not match vpnv4
|
||||||
vrf_nei = get_profile("zte.bgp_vpnv4_vrf_neighbor_in")
|
vrf_nei = get_profile("zte.bgp_vpnv4_vrf_neighbor_in")
|
||||||
assert vrf_nei is not None
|
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)
|
shared = shared_discover_placeholders(vrf_nei)
|
||||||
self.assertEqual(len(shared), 2)
|
self.assertEqual(len(shared), 2)
|
||||||
self.assertTrue(all(ph.discover_profile_id == "zte.config_bgp_peer" for ph in shared))
|
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]["afi"], "vpnv6")
|
||||||
self.assertEqual(routes[0]["direction"], "in")
|
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__":
|
if __name__ == "__main__":
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue