8888RE_BGP_REMOTE_AS = re .compile (r"remote AS (" + ASN_REGEX + r")" )
8989RE_BGP_AS_PATH = re .compile (r"^[ ]{2}([\d\(]([\d\) ]+)|Local)" )
9090
91+ RE_RP_ROUTE = re .compile (r"Routing entry for (" + IP_ADDR_REGEX + r"\/\d+)" )
9192RE_RP_FROM = re .compile (r"Known via \"([a-z]+)[ \"]" )
9293RE_RP_VIA = re .compile (r"via (\S+)" )
9394RE_RP_METRIC = re .compile (r"[ ]+Route metric is (\d+)" )
@@ -2322,7 +2323,7 @@ def get_arp_table(self, vrf=""):
23222323
23232324 try :
23242325 if age == "-" :
2325- age = 0
2326+ age = - 1
23262327 age = float (age )
23272328 except ValueError :
23282329 raise ValueError ("Unable to convert age value to float: {}" .format (age ))
@@ -2696,18 +2697,22 @@ def process_mac_fields(vlan, mac, mac_type, interface):
26962697
26972698 def get_probes_config (self ):
26982699 probes = {}
2700+
26992701 probes_regex = (
27002702 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+)))"
27052709 )
2710+
27062711 probe_args = {
27072712 "icmp-echo" : r"^(?P<target>\S+)\s+source-(?:ip|interface)\s+(?P<source>\S+)$"
27082713 }
27092714 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]"
27112716 output = self ._send_command (command )
27122717 for match in re .finditer (probes_regex , output , re .M ):
27132718 probe = match .groupdict ()
@@ -2723,8 +2728,8 @@ def get_probes_config(self):
27232728 "probe_type" : probe_type_map [probe ["probe_type" ]],
27242729 "target" : probe_data ["target" ],
27252730 "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 " ]),
27282733 }
27292734 }
27302735
@@ -2773,7 +2778,7 @@ def _get_bgp_route_attr(self, destination, vrf, next_hop, ip_version=4):
27732778
27742779 search_re_dict = {
27752780 "aspath" : {
2776- "re" : r"[^|\\n][ ]{2}([\d\(\)]([\d\(\) ])*)" ,
2781+ "re" : r"[^|\\n][ ]{2}([\d\(\)]([\d\(\) ])*|Local )" ,
27772782 "group" : 1 ,
27782783 "default" : "" ,
27792784 },
@@ -2947,8 +2952,11 @@ def get_route_to(self, destination="", protocol="", longer=False):
29472952 vrfs .append ("default" ) # global VRF
29482953 ipnet_dest = IPNetwork (destination )
29492954 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 : []}
29522960 commands = []
29532961 for _vrf in vrfs :
29542962 if _vrf == "default" :
@@ -2969,6 +2977,14 @@ def get_route_to(self, destination="", protocol="", longer=False):
29692977 for (outitem , _vrf ) in zip (output , vrfs ): # for all VRFs
29702978 route_proto_regex = RE_RP_FROM .search (outitem )
29712979 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 ] = []
29722988 # routing protocol name (bgp, ospf, ...)
29732989 route_proto = route_proto_regex .group (1 )
29742990 rdb = outitem .split ("Routing Descriptor Blocks:" )
@@ -3037,7 +3053,7 @@ def get_route_to(self, destination="", protocol="", longer=False):
30373053 nh_line_found = (
30383054 False # for next RT entry processing ...
30393055 )
3040- routes [destination ].append (route_entry )
3056+ routes [route_match ].append (route_entry )
30413057 return routes
30423058
30433059 def get_snmp_information (self ):
@@ -3405,7 +3421,14 @@ def get_network_instances(self, name=""):
34053421 if "No interfaces" in first_part :
34063422 interfaces = {}
34073423 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 ]
34093432
34103433 instances [vrf_name ] = {
34113434 "name" : vrf_name ,
0 commit comments