@@ -782,11 +782,6 @@ def build_prefix_limit(**args):
782
782
def get_bgp_neighbors_detail (self , neighbor_address = '' ):
783
783
"""Detailed view of the BGP neighbors operational data."""
784
784
bgp_neighbors = {}
785
- bgp_neighbors_table = junos_views .junos_bgp_neighbors_table (self .device )
786
- bgp_neighbors_table .get (
787
- neighbor_address = neighbor_address
788
- )
789
- bgp_neighbors_items = bgp_neighbors_table .items ()
790
785
default_neighbor_details = {
791
786
'up' : False ,
792
787
'local_as' : 0 ,
@@ -824,7 +819,6 @@ def get_bgp_neighbors_detail(self, neighbor_address=''):
824
819
'advertised_prefix_count' : - 1 ,
825
820
'flap_count' : 0
826
821
}
827
-
828
822
OPTION_KEY_MAP = {
829
823
'RemovePrivateAS' : 'remove_private_as' ,
830
824
'Multipath' : 'multipath' ,
@@ -836,87 +830,98 @@ def get_bgp_neighbors_detail(self, neighbor_address=''):
836
830
# Preference, HoldTime, Ttl, LogUpDown, Refresh
837
831
}
838
832
839
- JUNOS_DEFAULT_VRF_TABLES = (
840
- 'inet.0' ,
841
- 'inet6.0' ,
842
- 'inetflow.0'
843
- )
833
+ def _bgp_iter_core (neighbor_data , instance = None ):
834
+ '''
835
+ Iterate over a list of neighbors.
836
+ For older junos, the routing instance is not specified inside the
837
+ BGP neighbors XML, therefore we need to use a super sub-optimal structure
838
+ as in get_bgp_neighbors: iterate through the list of network instances
839
+ then execute one request for each and every routing instance.
840
+ For newer junos, this is not necessary as the routing instance is available
841
+ and we can get everything solve in a single request.
842
+ '''
843
+ for bgp_neighbor in neighbor_data :
844
+ remote_as = int (bgp_neighbor [0 ])
845
+ neighbor_details = deepcopy (default_neighbor_details )
846
+ neighbor_details .update (
847
+ {elem [0 ]: elem [1 ] for elem in bgp_neighbor [1 ] if elem [1 ] is not None }
848
+ )
849
+ if not instance :
850
+ peer_fwd_rti = neighbor_details .pop ('peer_fwd_rti' )
851
+ instance = peer_fwd_rti
852
+ else :
853
+ peer_fwd_rti = neighbor_details .pop ('peer_fwd_rti' , '' )
854
+ instance_name = 'global' if instance == 'master' else instance
855
+ options = neighbor_details .pop ('options' , '' )
856
+ if isinstance (options , str ):
857
+ options_list = options .split ()
858
+ for option in options_list :
859
+ key = OPTION_KEY_MAP .get (option )
860
+ if key is not None :
861
+ neighbor_details [key ] = True
862
+ four_byte_as = neighbor_details .pop ('4byte_as' , 0 )
863
+ local_address = neighbor_details .pop ('local_address' , '' )
864
+ local_details = local_address .split ('+' )
865
+ neighbor_details ['local_address' ] = napalm_base .helpers .convert (
866
+ napalm_base .helpers .ip , local_details [0 ], local_details [0 ])
867
+ if len (local_details ) == 2 :
868
+ neighbor_details ['local_port' ] = int (local_details [1 ])
869
+ else :
870
+ neighbor_details ['local_port' ] = 179
871
+ neighbor_details ['suppress_4byte_as' ] = (remote_as != four_byte_as )
872
+ peer_address = neighbor_details .pop ('peer_address' , '' )
873
+ remote_details = peer_address .split ('+' )
874
+ neighbor_details ['remote_address' ] = napalm_base .helpers .convert (
875
+ napalm_base .helpers .ip , remote_details [0 ], remote_details [0 ])
876
+ if len (remote_details ) == 2 :
877
+ neighbor_details ['remote_port' ] = int (remote_details [1 ])
878
+ else :
879
+ neighbor_details ['remote_port' ] = 179
880
+ neighbor_details ['routing_table' ] = instance_name
881
+ neighbors_rib = neighbor_details .pop ('rib' )
882
+ neighbors_queue = neighbor_details .pop ('queue' )
883
+ messages_queued_out = 0
884
+ for queue_entry in neighbors_queue .items ():
885
+ messages_queued_out += queue_entry [1 ][0 ][1 ]
886
+ neighbor_details ['messages_queued_out' ] = messages_queued_out
887
+ if instance_name not in bgp_neighbors .keys ():
888
+ bgp_neighbors [instance_name ] = {}
889
+ if remote_as not in bgp_neighbors [instance_name ].keys ():
890
+ bgp_neighbors [instance_name ][remote_as ] = []
891
+ neighbor_rib_stats = neighbors_rib .items ()
892
+ if not neighbor_rib_stats :
893
+ bgp_neighbors [instance_name ][remote_as ].append (neighbor_details )
894
+ continue # no RIBs available, pass default details
895
+ neighbor_rib_details = {
896
+ 'active_prefix_count' : 0 ,
897
+ 'received_prefix_count' : 0 ,
898
+ 'accepted_prefix_count' : 0 ,
899
+ 'suppressed_prefix_count' : 0 ,
900
+ 'advertised_prefix_count' : 0
901
+ }
902
+ for rib_entry in neighbor_rib_stats :
903
+ for elem in rib_entry [1 ]:
904
+ neighbor_rib_details [elem [0 ]] += elem [1 ]
905
+ neighbor_details .update (neighbor_rib_details )
906
+ bgp_neighbors [instance_name ][remote_as ].append (neighbor_details )
844
907
845
908
old_junos = napalm_base .helpers .convert (
846
909
int , self .device .facts .get ('version' , '0.0' ).split ('.' )[0 ], '0' ) < 13
910
+ bgp_neighbors_table = junos_views .junos_bgp_neighbors_table (self .device )
847
911
848
- for bgp_neighbor in bgp_neighbors_items :
849
- remote_as = int (bgp_neighbor [0 ])
850
- neighbor_details = deepcopy (default_neighbor_details )
851
- neighbor_details .update (
852
- {elem [0 ]: elem [1 ] for elem in bgp_neighbor [1 ] if elem [1 ] is not None }
853
- )
854
- options = neighbor_details .pop ('options' , '' )
855
- if isinstance (options , str ):
856
- options_list = options .split ()
857
- for option in options_list :
858
- key = OPTION_KEY_MAP .get (option )
859
- if key is not None :
860
- neighbor_details [key ] = True
861
- four_byte_as = neighbor_details .pop ('4byte_as' , 0 )
862
- local_address = neighbor_details .pop ('local_address' , '' )
863
- local_details = local_address .split ('+' )
864
- neighbor_details ['local_address' ] = napalm_base .helpers .convert (
865
- napalm_base .helpers .ip , local_details [0 ], local_details [0 ])
866
- if len (local_details ) == 2 :
867
- neighbor_details ['local_port' ] = int (local_details [1 ])
868
- else :
869
- neighbor_details ['local_port' ] = 179
870
- neighbor_details ['suppress_4byte_as' ] = (remote_as != four_byte_as )
871
- peer_address = neighbor_details .pop ('peer_address' , '' )
872
- remote_details = peer_address .split ('+' )
873
- neighbor_details ['remote_address' ] = napalm_base .helpers .convert (
874
- napalm_base .helpers .ip , remote_details [0 ], remote_details [0 ])
875
- if len (remote_details ) == 2 :
876
- neighbor_details ['remote_port' ] = int (remote_details [1 ])
877
- else :
878
- neighbor_details ['remote_port' ] = 179
879
- neighbors_rib = neighbor_details .pop ('rib' )
880
- neighbors_queue = neighbor_details .pop ('queue' )
881
- if old_junos :
882
- # anyway need to pop both
883
- # for Junos < 13, under the bgp-output-queue hierarchy
884
- # the table-name does not exist, hence we cannot match
885
- # but each table has an index that we can use later
886
- # the structure under old_queue is similar to queue,
887
- # but the key is the integer representing the table ID
888
- neighbors_queue = neighbor_details .pop ('old_queue' )
889
- else :
890
- neighbor_details .pop ('old_queue' )
891
- neighbor_queue_rib = {}
892
- for queue_entry in neighbors_queue .items ():
893
- neighbor_queue_rib [queue_entry [0 ]] = queue_entry [1 ][0 ][1 ]
894
- rib_id = 0
895
- if not old_junos :
896
- # for Junos >= 13, the table index starts from 1,
897
- # while older versions have 0 as the first table
898
- rib_id += 1
899
- for rib_entry in neighbors_rib .items ():
900
- _table = py23_compat .text_type (rib_entry [0 ])
901
- if _table in JUNOS_DEFAULT_VRF_TABLES :
902
- _table = 'global'
903
- if _table not in bgp_neighbors .keys ():
904
- bgp_neighbors [_table ] = {}
905
- if remote_as not in bgp_neighbors [_table ].keys ():
906
- bgp_neighbors [_table ][remote_as ] = []
907
- neighbor_rib_details = deepcopy (neighbor_details )
908
- neighbor_rib_details .update ({
909
- elem [0 ]: elem [1 ] for elem in rib_entry [1 ]
910
- })
911
- if old_junos :
912
- # in some cases this information might not exist at all...
913
- neighbor_rib_details ['messages_queued_out' ] = \
914
- neighbor_queue_rib .get (str (rib_id ), - 1 )
915
- else :
916
- neighbor_rib_details ['messages_queued_out' ] = neighbor_queue_rib [rib_entry [0 ]]
917
- neighbor_rib_details ['routing_table' ] = py23_compat .text_type (rib_entry [0 ])
918
- bgp_neighbors [_table ][remote_as ].append (neighbor_rib_details )
919
- rib_id += 1
912
+ if old_junos :
913
+ instances = junos_views .junos_route_instance_table (self .device )
914
+ for instance , instance_data in instances .get ().items ():
915
+ if instance .startswith ('__' ):
916
+ # junos internal instances
917
+ continue
918
+ neighbor_data = bgp_neighbors_table .get (instance = instance ,
919
+ neighbor_address = neighbor_address ).items ()
920
+ _bgp_iter_core (neighbor_data , instance = instance )
921
+ else :
922
+ bgp_neighbors_table = junos_views .junos_bgp_neighbors_table (self .device )
923
+ neighbor_data = bgp_neighbors_table .get (neighbor_address = neighbor_address ).items ()
924
+ _bgp_iter_core (neighbor_data )
920
925
return bgp_neighbors
921
926
922
927
def get_arp_table (self ):
0 commit comments