88
88
RE_BGP_REMOTE_AS = re .compile (r"remote AS (" + ASN_REGEX + r")" )
89
89
RE_BGP_AS_PATH = re .compile (r"^[ ]{2}([\d\(]([\d\) ]+)|Local)" )
90
90
91
+ RE_RP_ROUTE = re .compile (r"Routing entry for (" + IP_ADDR_REGEX + r"\/\d+)" )
91
92
RE_RP_FROM = re .compile (r"Known via \"([a-z]+)[ \"]" )
92
93
RE_RP_VIA = re .compile (r"via (\S+)" )
93
94
RE_RP_METRIC = re .compile (r"[ ]+Route metric is (\d+)" )
@@ -2322,7 +2323,7 @@ def get_arp_table(self, vrf=""):
2322
2323
2323
2324
try :
2324
2325
if age == "-" :
2325
- age = 0
2326
+ age = - 1
2326
2327
age = float (age )
2327
2328
except ValueError :
2328
2329
raise ValueError ("Unable to convert age value to float: {}" .format (age ))
@@ -2696,18 +2697,22 @@ def process_mac_fields(vlan, mac, mac_type, interface):
2696
2697
2697
2698
def get_probes_config (self ):
2698
2699
probes = {}
2700
+
2699
2701
probes_regex = (
2700
2702
r"ip\s+sla\s+(?P<id>\d+)\n"
2701
- r"\s+(?P<probe_type>\S+)\s+(?P<probe_args>.*\n).*"
2702
- r"\s+tag\s+(?P<name>\S+)\n.*"
2703
- r"\s+history\s+buckets-kept\s+(?P<probe_count>\d+)\n.*"
2704
- r"\s+frequency\s+(?P<interval>\d+)$"
2703
+ r"\s+(?P<probe_type>\S+)\s+(?P<probe_args>.*)\n"
2704
+ r"\s+tag\s+(?P<name>[\S ]+)\n"
2705
+ r"(\s+.*\n)*"
2706
+ r"((\s+frequency\s+(?P<interval0>\d+)\n(\s+.*\n)*\s+history"
2707
+ r"\s+buckets-kept\s+(?P<probe_count0>\d+))|(\s+history\s+buckets-kept"
2708
+ r"\s+(?P<probe_count1>\d+)\n.*\s+frequency\s+(?P<interval1>\d+)))"
2705
2709
)
2710
+
2706
2711
probe_args = {
2707
2712
"icmp-echo" : r"^(?P<target>\S+)\s+source-(?:ip|interface)\s+(?P<source>\S+)$"
2708
2713
}
2709
2714
probe_type_map = {"icmp-echo" : "icmp-ping" }
2710
- command = "show run | include ip sla [0-9]"
2715
+ command = "show run | section ip sla [0-9]"
2711
2716
output = self ._send_command (command )
2712
2717
for match in re .finditer (probes_regex , output , re .M ):
2713
2718
probe = match .groupdict ()
@@ -2723,8 +2728,8 @@ def get_probes_config(self):
2723
2728
"probe_type" : probe_type_map [probe ["probe_type" ]],
2724
2729
"target" : probe_data ["target" ],
2725
2730
"source" : probe_data ["source" ],
2726
- "probe_count" : int (probe ["probe_count " ]),
2727
- "test_interval" : int (probe ["interval " ]),
2731
+ "probe_count" : int (probe ["probe_count0" ] or probe [ "probe_count1 " ]),
2732
+ "test_interval" : int (probe ["interval0" ] or probe [ "interval1 " ]),
2728
2733
}
2729
2734
}
2730
2735
@@ -2773,7 +2778,7 @@ def _get_bgp_route_attr(self, destination, vrf, next_hop, ip_version=4):
2773
2778
2774
2779
search_re_dict = {
2775
2780
"aspath" : {
2776
- "re" : r"[^|\\n][ ]{2}([\d\(\)]([\d\(\) ])*)" ,
2781
+ "re" : r"[^|\\n][ ]{2}([\d\(\)]([\d\(\) ])*|Local )" ,
2777
2782
"group" : 1 ,
2778
2783
"default" : "" ,
2779
2784
},
@@ -2947,8 +2952,11 @@ def get_route_to(self, destination="", protocol="", longer=False):
2947
2952
vrfs .append ("default" ) # global VRF
2948
2953
ipnet_dest = IPNetwork (destination )
2949
2954
prefix = str (ipnet_dest .network )
2950
- netmask = str (ipnet_dest .netmask )
2951
- routes = {destination : []}
2955
+ netmask = ""
2956
+ routes = {}
2957
+ if "/" in destination :
2958
+ netmask = str (ipnet_dest .netmask )
2959
+ routes = {destination : []}
2952
2960
commands = []
2953
2961
for _vrf in vrfs :
2954
2962
if _vrf == "default" :
@@ -2969,6 +2977,14 @@ def get_route_to(self, destination="", protocol="", longer=False):
2969
2977
for (outitem , _vrf ) in zip (output , vrfs ): # for all VRFs
2970
2978
route_proto_regex = RE_RP_FROM .search (outitem )
2971
2979
if route_proto_regex :
2980
+ route_match = destination
2981
+ if netmask == "" :
2982
+ # Get the matching route for a non-exact lookup
2983
+ route_match_regex = RE_RP_ROUTE .search (outitem )
2984
+ if route_match_regex :
2985
+ route_match = route_match_regex .group (1 )
2986
+ if route_match not in routes :
2987
+ routes [route_match ] = []
2972
2988
# routing protocol name (bgp, ospf, ...)
2973
2989
route_proto = route_proto_regex .group (1 )
2974
2990
rdb = outitem .split ("Routing Descriptor Blocks:" )
@@ -3037,7 +3053,7 @@ def get_route_to(self, destination="", protocol="", longer=False):
3037
3053
nh_line_found = (
3038
3054
False # for next RT entry processing ...
3039
3055
)
3040
- routes [destination ].append (route_entry )
3056
+ routes [route_match ].append (route_entry )
3041
3057
return routes
3042
3058
3043
3059
def get_snmp_information (self ):
@@ -3405,7 +3421,14 @@ def get_network_instances(self, name=""):
3405
3421
if "No interfaces" in first_part :
3406
3422
interfaces = {}
3407
3423
else :
3408
- interfaces = {itf : {} for itf in if_regex .group (1 ).split ()}
3424
+ interfaces = {
3425
+ canonical_interface_name (itf , {"Vl" : "Vlan" }): {}
3426
+ for itf in if_regex .group (1 ).split ()
3427
+ }
3428
+
3429
+ # remove interfaces in the VRF from the default VRF
3430
+ for item in interfaces :
3431
+ del instances ["default" ]["interfaces" ]["interface" ][item ]
3409
3432
3410
3433
instances [vrf_name ] = {
3411
3434
"name" : vrf_name ,
0 commit comments