Skip to content

Commit

Permalink
IOS: get_bgp_neighbor_detail (#727)
Browse files Browse the repository at this point in the history
* ios: Add support and tests for get_bgp_neighbors_detail

* ios: formatting get_bgp_neighbors_detail
  • Loading branch information
nickethier authored and dbarrosop committed Jun 3, 2018
1 parent 24f887b commit b0629e8
Show file tree
Hide file tree
Showing 13 changed files with 1,023 additions and 0 deletions.
113 changes: 113 additions & 0 deletions napalm/ios/ios.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import tempfile
import telnetlib
import copy
from collections import defaultdict

from netmiko import FileTransfer, InLineTransfer
from napalm.base.base import NetworkDriver
Expand Down Expand Up @@ -67,6 +68,20 @@
'show_mac_address': ['show mac-address-table', 'show mac address-table'],
}

AFI_COMMAND_MAP = {
'IPv4 Unicast': 'ipv4 unicast',
'IPv6 Unicast': 'ipv6 unicast',
'VPNv4 Unicast': 'vpnv4 all',
'VPNv6 Unicast': 'vpnv6 unicast all',
'IPv4 Multicast': 'ipv4 multicast',
'IPv6 Multicast': 'ipv6 multicast',
'L2VPN E-VPN': 'l2vpn evpn',
'MVPNv4 Unicast': 'ipv4 mvpn all',
'MVPNv6 Unicast': 'ipv6 mvpn all',
'VPNv4 Flowspec': 'ipv4 flowspec',
'VPNv6 Flowspec': 'ipv6 flowspec',
}


class IOSDriver(NetworkDriver):
"""NAPALM Cisco IOS Handler."""
Expand Down Expand Up @@ -1478,6 +1493,104 @@ def get_bgp_neighbors(self):
}
return bgp_neighbor_data

def get_bgp_neighbors_detail(self, neighbor_address=''):
bgp_detail = defaultdict(lambda: defaultdict(lambda: []))

raw_bgp_sum = self._send_command('show ip bgp all sum').strip()
bgp_sum = napalm.base.helpers.textfsm_extractor(
self, 'ip_bgp_all_sum', raw_bgp_sum)
for neigh in bgp_sum:
if neighbor_address and neighbor_address != neigh['neighbor']:
continue
raw_bgp_neigh = self._send_command('show ip bgp {} neigh {}'.format(
AFI_COMMAND_MAP[neigh['addr_family']], neigh['neighbor']))
bgp_neigh = napalm.base.helpers.textfsm_extractor(
self, 'ip_bgp_neigh', raw_bgp_neigh)[0]
details = {
'up': neigh['up'] != 'never',
'local_as': napalm.base.helpers.as_number(neigh['local_as']),
'remote_as': napalm.base.helpers.as_number(neigh['remote_as']),
'router_id': napalm.base.helpers.ip(
bgp_neigh['router_id']) if bgp_neigh['router_id'] else '',
'local_address': napalm.base.helpers.ip(
bgp_neigh['local_address']) if bgp_neigh['local_address'] else '',
'local_address_configured': False,
'local_port': napalm.base.helpers.as_number(
bgp_neigh['local_port']) if bgp_neigh['local_port'] else 0,
'routing_table': bgp_neigh['vrf'] if bgp_neigh['vrf'] else 'global',
'remote_address': napalm.base.helpers.ip(bgp_neigh['neighbor']),
'remote_port': napalm.base.helpers.as_number(
bgp_neigh['remote_port']) if bgp_neigh['remote_port'] else 0,
'multihop': False,
'multipath': False,
'remove_private_as': False,
'import_policy': '',
'export_policy': '',
'input_messages': napalm.base.helpers.as_number(
bgp_neigh['msg_total_in']) if bgp_neigh['msg_total_in'] else 0,
'output_messages': napalm.base.helpers.as_number(
bgp_neigh['msg_total_out']) if bgp_neigh['msg_total_out'] else 0,
'input_updates': napalm.base.helpers.as_number(
bgp_neigh['msg_update_in']) if bgp_neigh['msg_update_in'] else 0,
'output_updates': napalm.base.helpers.as_number(
bgp_neigh['msg_update_out']) if bgp_neigh['msg_update_out'] else 0,
'messages_queued_out': napalm.base.helpers.as_number(neigh['out_q']),
'connection_state': bgp_neigh['bgp_state'],
'previous_connection_state': '',
'last_event': '',
'suppress_4byte_as': (
bgp_neigh['four_byte_as'] != 'advertised and received' if
bgp_neigh['four_byte_as'] else False),
'local_as_prepend': False,
'holdtime': napalm.base.helpers.as_number(
bgp_neigh['holdtime']) if bgp_neigh['holdtime'] else 0,
'configured_holdtime': 0,
'keepalive': napalm.base.helpers.as_number(
bgp_neigh['keepalive']) if bgp_neigh['keepalive'] else 0,
'configured_keepalive': 0,
'active_prefix_count': 0,
'received_prefix_count': 0,
'accepted_prefix_count': 0,
'suppressed_prefix_count': 0,
'advertised_prefix_count': 0,
'flap_count': 0,
}

bgp_neigh_afi = napalm.base.helpers.textfsm_extractor(
self, 'ip_bgp_neigh_afi', raw_bgp_neigh)
if len(bgp_neigh_afi) > 1:
bgp_neigh_afi = bgp_neigh_afi[1]
details.update({
'local_address_configured': bgp_neigh_afi['local_addr_conf'] != '',
'multipath': bgp_neigh_afi['multipaths'] != '0',
'import_policy': bgp_neigh_afi['policy_in'],
'export_policy': bgp_neigh_afi['policy_out'],
'last_event': (
bgp_neigh_afi['last_event'] if
bgp_neigh_afi['last_event'] != 'never' else ''),
'active_prefix_count': napalm.base.helpers.as_number(
bgp_neigh_afi['bestpaths']),
'received_prefix_count': napalm.base.helpers.as_number(
bgp_neigh_afi['prefix_curr_in']) + napalm.base.helpers.as_number(
bgp_neigh_afi['rejected_prefix_in']),
'accepted_prefix_count': napalm.base.helpers.as_number(
bgp_neigh_afi['prefix_curr_in']),
'suppressed_prefix_count': napalm.base.helpers.as_number(
bgp_neigh_afi['rejected_prefix_in']),
'advertised_prefix_count': napalm.base.helpers.as_number(
bgp_neigh_afi['prefix_curr_out']),
'flap_count': napalm.base.helpers.as_number(bgp_neigh_afi['flap_count'])
})
else:
bgp_neigh_afi = bgp_neigh_afi[0]
details.update({
'import_policy': bgp_neigh_afi['policy_in'],
'export_policy': bgp_neigh_afi['policy_out'],
})
bgp_detail[details['routing_table']][
details['remote_as']].append(details)
return bgp_detail

def get_interfaces_counters(self):
"""
Return interface counters and errors.
Expand Down
24 changes: 24 additions & 0 deletions napalm/ios/utils/textfsm_templates/ip_bgp_all_sum.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
Value Filldown ADDR_FAMILY (.*)
Value Filldown ROUTER_ID (\S+)
Value Filldown LOCAL_AS (\d+)
Value NEIGHBOR (\S+)
Value BGP_VER (\d)
Value REMOTE_AS (\d+)
Value MSG_RECV (\d+)
Value MSG_SENT (\d+)
Value TBL_VER (\d+)
Value IN_Q (\d+)
Value OUT_Q (\d+)
Value UP (\w+)
Value PREFIX_RECV (.*)

Start
^For address family\: ${ADDR_FAMILY}
^BGP router identifier ${ROUTER_ID}, local AS number ${LOCAL_AS}
^Neighbor\s+V -> Table

Table
^${NEIGHBOR}\s+${BGP_VER}\s+${REMOTE_AS}\s+${MSG_RECV}\s+${MSG_SENT}\s+${TBL_VER}\s+${IN_Q}\s+${OUT_Q}\s+${UP}\s+${PREFIX_RECV} -> Record Table
^\s* -> Clearall Start

EOF
56 changes: 56 additions & 0 deletions napalm/ios/utils/textfsm_templates/ip_bgp_neigh.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
Value NEIGHBOR (\S+)
Value REMOTE_AS (\d+)
Value BGP_TYPE (\w+)
Value VRF (\w+)
Value DESCRIPTION (.*)
Value ROUTER_ID (\S+)
Value BGP_STATE (\w+)
Value UP (\w+)
Value UPTIME (\w+)
Value LAST_READ (.*)
Value LAST_WRITE (.*)
Value HOLDTIME (\d+)
Value KEEPALIVE (\d+)
Value FOUR_BYTE_AS (.*)
Value MSG_OPEN_OUT (\d+)
Value MSG_OPEN_IN (\d+)
Value MSG_NOTI_OUT (\d+)
Value MSG_NOTI_IN (\d+)
Value MSG_UPDATE_OUT (\d+)
Value MSG_UPDATE_IN (\d+)
Value MSG_KEEPALIVE_OUT (\d+)
Value MSG_KEEPALIVE_IN (\d+)
Value MSG_REFRESH_OUT (\d+)
Value MSG_REFRESH_IN (\d+)
Value MSG_TOTAL_OUT (\d+)
Value MSG_TOTAL_IN (\d+)
Value LOCAL_ADDRESS (.*)
Value LOCAL_PORT (\d+)
Value REMOTE_ADDRESS (.*)
Value REMOTE_PORT (\d+)
Value ROUTING_TABLE (\d+)
Value CONN_STATE (\w+)

Start
^BGP neighbor is ${NEIGHBOR},(?:\s+vrf ${VRF},)?\s+remote AS\s+${REMOTE_AS},\s+${BGP_TYPE} link
^\s+Administratively shut ${UP}
^\s+Description:\s+${DESCRIPTION}
^\s+BGP version 4, remote router ID ${ROUTER_ID}
^\s+BGP state = ${BGP_STATE}(?:, ${UP} for ${UPTIME})?
^\s+Last read ${LAST_READ}, last write ${LAST_WRITE}, hold time is ${HOLDTIME}, keepalive interval is ${KEEPALIVE} seconds
^\s+Four-octets ASN Capability:\s+${FOUR_BYTE_AS}
^\s+Opens:\s+${MSG_OPEN_OUT}\s+${MSG_OPEN_IN}
^\s+Notifications:\s+${MSG_NOTI_OUT}\s+${MSG_NOTI_IN}
^\s+Updates:\s+${MSG_UPDATE_OUT}\s+${MSG_UPDATE_IN}
^\s+Keepalives:\s+${MSG_KEEPALIVE_OUT}\s+${MSG_KEEPALIVE_IN}
^\s+Route Refresh:\s+${MSG_REFRESH_OUT}\s+${MSG_REFRESH_IN}
^\s+Total:\s+${MSG_TOTAL_OUT}\s+${MSG_TOTAL_IN}
^\s*Connection state is ${CONN_STATE},
^\s*For address family -> Afi
^Local host: ${LOCAL_ADDRESS}, Local port: ${LOCAL_PORT}
^Foreign host: ${REMOTE_ADDRESS}, Foreign port: ${REMOTE_PORT}
^Connection tableid \(VRF\): ${ROUTING_TABLE}

Afi
^\s -> Next
^\w -> Start
41 changes: 41 additions & 0 deletions napalm/ios/utils/textfsm_templates/ip_bgp_neigh_afi.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
Value AFI (.*)
Value SESSION (\S+)
Value POLICY_IN (\S+)
Value POLICY_OUT (\S+)
Value PREFIX_CURR_OUT (\d+)
Value PREFIX_CURR_IN (\d+)
Value PREFIX_TOTAL_OUT (\d+)
Value PREFIX_TOTAL_IN (\d+)
Value WITHDRAW_IMPLICIT_OUT (\d+)
Value WITHDRAW_IMPLICIT_IN (\d+)
Value WITHDRAW_EXPLICIT_OUT (\d+)
Value WITHDRAW_EXPLICIT_IN (\d+)
Value BESTPATHS (\d+)
Value MULTIPATHS (\d+)
Value SECONDARIES (\d+)
Value REJECTED_PREFIX_IN (\d+)
Value REJECTED_PREFIX_OUT (\d+)
Value FLAP_COUNT (\d+)
Value LAST_EVENT (.*)
Value LOCAL_ADDR_CONF (peering address in same link)

Start
^\s*For address family: -> Continue.Record
^\s*For address family: ${AFI}
^\s+Session: ${SESSION}
^\s+Route map for incoming advertisements is ${POLICY_IN}
^\s+Route map for outgoing advertisements is ${POLICY_OUT}
^\s+Prefixes Current:\s+${PREFIX_CURR_OUT}\s+${PREFIX_CURR_IN}
^\s+Prefixes Total:\s+${PREFIX_TOTAL_OUT}\s+${PREFIX_TOTAL_IN}
^\s+Implicit Withdraw:\s+${WITHDRAW_IMPLICIT_OUT}\s+${WITHDRAW_IMPLICIT_IN}
^\s+Explicit Withdraw:\s+${WITHDRAW_EXPLICIT_OUT}\s+${WITHDRAW_EXPLICIT_IN}
^\s+Used as bestpath:\s+\S+\s+${BESTPATHS}
^\s+Used as multipath:\s+\S+\s+${MULTIPATHS}
^\s+Used as secondary:\s+\S+\s+${SECONDARIES}
^\s+Total:\s+${REJECTED_PREFIX_OUT}\s+${REJECTED_PREFIX_IN}
^\s+Connections established\s+\d+;\s+dropped\s+${FLAP_COUNT}
^\s+Last reset ${LAST_EVENT}
^\s+Interface associated: \S+ \(${LOCAL_ADDR_CONF}\)
^Connection state is -> Record


Loading

0 comments on commit b0629e8

Please sign in to comment.