1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
|
import logging
import traceback
from os_ken.lib.packet.bgp import RouteFamily
from os_ken.lib.packet.bgp import RF_IPv4_UC
from os_ken.lib.packet.bgp import RF_IPv6_UC
from os_ken.lib.packet.bgp import RF_IPv4_VPN
from os_ken.lib.packet.bgp import RF_IPv6_VPN
from os_ken.lib.packet.bgp import RF_L2_EVPN
from os_ken.lib.packet.bgp import RF_IPv4_FLOWSPEC
from os_ken.lib.packet.bgp import RF_IPv6_FLOWSPEC
from os_ken.lib.packet.bgp import RF_VPNv4_FLOWSPEC
from os_ken.lib.packet.bgp import RF_VPNv6_FLOWSPEC
from os_ken.lib.packet.bgp import RF_L2VPN_FLOWSPEC
from os_ken.lib.packet.bgp import RF_RTC_UC
from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN
from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH
from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC
from os_ken.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF
from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP
from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP
from os_ken.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE
from os_ken.services.protocols.bgp.base import add_bgp_error_metadata
from os_ken.services.protocols.bgp.base import BGPSException
from os_ken.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF
from os_ken.services.protocols.bgp.core_manager import CORE_MANAGER
LOG = logging.getLogger('bgpspeaker.operator.internal_api')
INTERNAL_API_ERROR = 100
INTERNAL_API_SUB_ERROR = 101
class InternalApi(object):
def __init__(self, log_handler=None):
self.log_handler = log_handler
def count_all_vrf_routes(self):
vrf_tables = self._get_vrf_tables()
ret = {}
for key in vrf_tables.keys():
vrf_name, vrf_rf = key
ret.update(self.count_single_vrf_routes(vrf_name, vrf_rf))
return ret
def count_single_vrf_routes(self, vrf_name, vrf_rf):
vrf = self._get_vrf_tables().get((vrf_name, vrf_rf))
if vrf is None:
raise WrongParamError('wrong vpn key %s' % str((vrf_name, vrf_rf)))
vrf_name = vrf_name.encode('ascii', 'ignore')
route_count = \
len([d for d in vrf.values() if d.best_path])
return {str((vrf_name, vrf_rf)): route_count}
def get_vrfs_conf(self):
return CORE_MANAGER.vrfs_conf.vrfs_by_rd_rf_id
def get_all_vrf_routes(self):
vrfs = self._get_vrf_tables()
ret = {}
for (vrf_id, vrf_rf), table in sorted(vrfs.items()):
ret[str((vrf_id, vrf_rf))] = self._get_single_vrf_routes(table)
return ret
def get_single_vrf_routes(self, vrf_id, vrf_rf):
vrf = self._get_vrf_table(vrf_id, vrf_rf)
if not vrf:
raise WrongParamError('wrong vpn name %s' % str((vrf_id, vrf_rf)))
return [self._dst_to_dict(d) for d in vrf.values()]
def _get_single_vrf_routes(self, vrf_table):
return [self._dst_to_dict(d) for d in vrf_table.values()]
def _get_vrf_table(self, vrf_name, vrf_rf):
return CORE_MANAGER.get_core_service()\
.table_manager.get_vrf_table(vrf_name, vrf_rf)
def _get_vrf_tables(self):
return CORE_MANAGER.get_core_service().table_manager.get_vrf_tables()
def get_single_rib_routes(self, addr_family):
rfs = {
'ipv4': RF_IPv4_UC,
'ipv6': RF_IPv6_UC,
'vpnv4': RF_IPv4_VPN,
'vpnv6': RF_IPv6_VPN,
'evpn': RF_L2_EVPN,
'ipv4fs': RF_IPv4_FLOWSPEC,
'ipv6fs': RF_IPv6_FLOWSPEC,
'vpnv4fs': RF_VPNv4_FLOWSPEC,
'vpnv6fs': RF_VPNv6_FLOWSPEC,
'l2vpnfs': RF_L2VPN_FLOWSPEC,
'rtfilter': RF_RTC_UC
}
if addr_family not in rfs:
raise WrongParamError('Unknown or unsupported family: %s' %
addr_family)
rf = rfs.get(addr_family)
table_manager = self.get_core_service().table_manager
gtable = table_manager.get_global_table_by_route_family(rf)
if gtable is not None:
return [self._dst_to_dict(dst)
for dst in sorted(gtable.values())]
else:
return []
def _dst_to_dict(self, dst):
ret = {'paths': [],
'prefix': dst.nlri_str}
def _path_to_dict(dst, path):
path_seg_list = path.get_pattr(BGP_ATTR_TYPE_AS_PATH).path_seg_list
if isinstance(path_seg_list, list):
aspath = []
for as_path_seg in path_seg_list:
for as_num in as_path_seg:
aspath.append(as_num)
else:
aspath = ''
origin = path.get_pattr(BGP_ATTR_TYPE_ORIGIN)
origin = origin.value if origin else None
if origin == BGP_ATTR_ORIGIN_IGP:
origin = 'i'
elif origin == BGP_ATTR_ORIGIN_EGP:
origin = 'e'
elif origin == BGP_ATTR_ORIGIN_INCOMPLETE:
origin = '?'
nexthop = path.nexthop
# Get the MED path attribute
med = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC)
med = med.value if med else ''
# Get best path reason
bpr = dst.best_path_reason if path == dst.best_path else ''
# Get local preference
localpref = path.get_pattr(BGP_ATTR_TYPE_LOCAL_PREF)
localpref = localpref.value if localpref else ''
if hasattr(path.nlri, 'label_list'):
labels = path.nlri.label_list
else:
labels = None
return {'best': (path == dst.best_path),
'bpr': bpr,
'prefix': path.nlri_str,
'labels': labels,
'nexthop': nexthop,
'metric': med,
'aspath': aspath,
'origin': origin,
'localpref': localpref}
for path in dst.known_path_list:
ret['paths'].append(_path_to_dict(dst, path))
return ret
def check_logging(self):
return self.log_handler and self._has_log_handler(self.log_handler)
def check_logging_level(self):
return logging.getLevelName(self.log_handler.level)
def _has_log_handler(self, log_handler):
if log_handler in logging.getLogger('bgpspeaker').handlers:
return True
return False
def route_refresh(self, peer_ip=None, afi=None, safi=None):
if not peer_ip:
peer_ip = 'all'
try:
route_families = []
if afi is None and safi is None:
route_families.extend(SUPPORTED_GLOBAL_RF)
else:
route_family = RouteFamily(afi, safi)
if route_family not in SUPPORTED_GLOBAL_RF:
raise WrongParamError('Not supported address-family'
' %s, %s' % (afi, safi))
route_families.append(route_family)
pm = CORE_MANAGER.get_core_service().peer_manager
pm.make_route_refresh_request(peer_ip, *route_families)
except Exception as e:
LOG.error(traceback.format_exc())
raise WrongParamError(str(e))
return None
def get_core_service(self):
return CORE_MANAGER.get_core_service()
@add_bgp_error_metadata(code=INTERNAL_API_ERROR,
sub_code=INTERNAL_API_SUB_ERROR,
def_desc='Unknown internal api exception.')
class WrongParamError(BGPSException):
pass
|