1212_execute_after = [ 'ebgp.utils' , 'bgp.session' ]
1313_requires = [ 'bgp' ]
1414
15- def pre_transform (topology : Box ) -> None :
16- global _config_name
17- session_idx = data .find_in_list (['ebgp.utils' ,'bgp.session' ],topology .plugin )
18- multihop_idx = data .find_in_list ([ _config_name ],topology .plugin )
19-
20- if session_idx is not None and multihop_idx is not None and session_idx > multihop_idx :
21- log .error (
22- 'ebgp.multihop plugin must be included after bgp.session/ebgp.utils plugin' ,
23- log .IncorrectValue ,'ebgp.multihop' )
24-
2515def pre_link_transform (topology : Box ) -> None :
2616 if not 'multihop' in topology .get ('bgp' ,{}):
2717 return
@@ -41,7 +31,7 @@ def pre_link_transform(topology: Box) -> None:
4131
4232 s .type = 'tunnel'
4333 s .linkindex = links .get_next_linkindex (topology )
44- s ._bgp_session = True
34+ s ._phantom_link = True
4535
4636 validate_attributes (
4737 data = s , # Validate pseudo-link data
@@ -82,7 +72,7 @@ def pre_link_transform(topology: Box) -> None:
8272 intf .bgp .multihop = 255
8373 if 'vrf' in intf :
8474 intf .bgp ._vrf = intf .vrf
85- intf ._bgp_session = True
75+ intf ._mh_bgp_session = True
8676 intf ._phantom_link = True
8777 intf .ifname = f'_ebgp_multihop_{ s .linkindex } '
8878
@@ -137,28 +127,17 @@ def augment_af_activation(ndata: Box, topology: Box) -> None:
137127 chg .pop (bgp_af ,None ) # Otherwise remove it
138128
139129'''
140- remove_fake_interfaces: remove all fake interfaces created to build BGP neighbor adjacencies
130+ Check whether a node has EBGP multihop sessions
141131'''
142- def remove_fake_interfaces (ndata : Box , topology : Box ) -> bool :
143- intf_count = len (ndata .interfaces )
144- ndata .interfaces = [ intf for intf in ndata .interfaces if not intf .get ('_bgp_session' ,None ) ]
132+ def ebgp_multihop_sessions (ndata : Box , topology : Box ) -> bool :
133+ mh_intf = [ intf for intf in ndata .interfaces if intf .get ('_mh_bgp_session' ,False ) ]
134+ if not mh_intf : # Do we have any fake interfaces for MH EBGP sessions?
135+ return False
145136
146- return len (ndata .interfaces ) != intf_count
147-
148- '''
149- cleanup_interfaces: remove fake interfaces from global interface list and VRF OSPF interface list
150- '''
151- def cleanup_interfaces (ndata : Box , topology : Box ) -> None :
152- changed = remove_fake_interfaces (ndata ,topology ) # Cleanup global interface list
153- for vname ,vdata in ndata .get ('vrfs' ,{}).items (): # Iterate over VRFs
154- if 'ospf' in vdata : # .. and cleanup OSPF interface list if needed
155- v_chg = remove_fake_interfaces (vdata .ospf ,topology )
156- changed = changed or v_chg
157-
158- if changed : # Did the interface count change?
159- check_multihop_support (ndata ,topology )
160- api .node_config (ndata ,_config_name ) # We must have some multihop sessions, add extra config
161- augment_af_activation (ndata ,topology )
137+ check_multihop_support (ndata ,topology ) # Check that the node supports it
138+ api .node_config (ndata ,_config_name ) # We must have some multihop sessions, add extra config
139+ augment_af_activation (ndata ,topology ) # ... and activate relevant address families on these sessions
140+ return True
162141
163142'''
164143fix_vrf_loopbacks:
@@ -180,7 +159,7 @@ def fix_vrf_loopbacks(ndata: Box, topology: Box) -> None:
180159 if af in lb : # ... removing whatever might have come from the
181160 ngb [af ] = str (ipaddress .ip_interface (lb [af ]).ip ) # ... global loopback
182161
183- if '_src_vrf' in ngb : # Is out endpoint in a VRF?
162+ if '_src_vrf' in ngb : # Is our endpoint in a VRF?
184163 if not isinstance (features .bgp .multihop ,Box ) or features .bgp .multihop .vrf is not True :
185164 log .error (
186165 f'Device { ndata .device } does not support VRF EBGP multihop sessions (node { ndata .name } , VRF { ngb ._src_vrf } )' ,
@@ -212,7 +191,14 @@ def fix_vrf_loopbacks(ndata: Box, topology: Box) -> None:
212191def post_transform (topology : Box ) -> None :
213192 global _config_name
214193 for ndata in topology .nodes .values ():
215- fix_vrf_loopbacks (ndata ,topology )
216- cleanup_interfaces (ndata ,topology )
194+ if ebgp_multihop_sessions (ndata ,topology ):
195+ fix_vrf_loopbacks (ndata ,topology )
196+
197+ '''
198+ Cleanup: remove interfaces and links with _phantom_link flag
199+ '''
200+ def cleanup (topology : Box ) -> None :
201+ for ndata in topology .nodes .values ():
202+ ndata .interfaces = [ intf for intf in ndata .interfaces if not intf .get ('_phantom_link' ,None ) ]
217203
218- topology .links = [ link for link in topology .links if not link .get ('_bgp_session ' ,None ) ]
204+ topology .links = [ link for link in topology .links if not link .get ('_phantom_link ' ,None ) ]
0 commit comments