4 from ryu.lib.packet.bgp import RouteFamily
5 from ryu.lib.packet.bgp import RF_IPv4_UC
6 from ryu.lib.packet.bgp import RF_IPv6_UC
7 from ryu.lib.packet.bgp import RF_IPv4_VPN
8 from ryu.lib.packet.bgp import RF_IPv6_VPN
9 from ryu.lib.packet.bgp import RF_L2_EVPN
10 from ryu.lib.packet.bgp import RF_IPv4_FLOWSPEC
11 from ryu.lib.packet.bgp import RF_IPv6_FLOWSPEC
12 from ryu.lib.packet.bgp import RF_VPNv4_FLOWSPEC
13 from ryu.lib.packet.bgp import RF_VPNv6_FLOWSPEC
14 from ryu.lib.packet.bgp import RF_L2VPN_FLOWSPEC
15 from ryu.lib.packet.bgp import RF_RTC_UC
16 from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN
17 from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH
18 from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC
19 from ryu.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF
20 from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP
21 from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP
22 from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE
24 from ryu.services.protocols.bgp.base import add_bgp_error_metadata
25 from ryu.services.protocols.bgp.base import BGPSException
26 from ryu.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF
27 from ryu.services.protocols.bgp.core_manager import CORE_MANAGER
30 LOG = logging.getLogger('bgpspeaker.operator.internal_api')
32 INTERNAL_API_ERROR = 100
33 INTERNAL_API_SUB_ERROR = 101
36 class InternalApi(object):
38 def __init__(self, log_handler=None):
39 self.log_handler = log_handler
41 def count_all_vrf_routes(self):
42 vrf_tables = self._get_vrf_tables()
44 for key in vrf_tables.keys():
45 vrf_name, vrf_rf = key
46 ret.update(self.count_single_vrf_routes(vrf_name, vrf_rf))
49 def count_single_vrf_routes(self, vrf_name, vrf_rf):
50 vrf = self._get_vrf_tables().get((vrf_name, vrf_rf))
52 raise WrongParamError('wrong vpn key %s' % str((vrf_name, vrf_rf)))
53 vrf_name = vrf_name.encode('ascii', 'ignore')
56 len([d for d in vrf.values() if d.best_path])
57 return {str((vrf_name, vrf_rf)): route_count}
59 def get_vrfs_conf(self):
60 return CORE_MANAGER.vrfs_conf.vrfs_by_rd_rf_id
62 def get_all_vrf_routes(self):
63 vrfs = self._get_vrf_tables()
65 for (vrf_id, vrf_rf), table in sorted(vrfs.items()):
66 ret[str((vrf_id, vrf_rf))] = self._get_single_vrf_routes(table)
69 def get_single_vrf_routes(self, vrf_id, vrf_rf):
70 vrf = self._get_vrf_table(vrf_id, vrf_rf)
72 raise WrongParamError('wrong vpn name %s' % str((vrf_id, vrf_rf)))
73 return [self._dst_to_dict(d) for d in vrf.values()]
75 def _get_single_vrf_routes(self, vrf_table):
76 return [self._dst_to_dict(d) for d in vrf_table.values()]
78 def _get_vrf_table(self, vrf_name, vrf_rf):
79 return CORE_MANAGER.get_core_service()\
80 .table_manager.get_vrf_table(vrf_name, vrf_rf)
82 def _get_vrf_tables(self):
83 return CORE_MANAGER.get_core_service().table_manager.get_vrf_tables()
85 def get_single_rib_routes(self, addr_family):
92 'ipv4fs': RF_IPv4_FLOWSPEC,
93 'ipv6fs': RF_IPv6_FLOWSPEC,
94 'vpnv4fs': RF_VPNv4_FLOWSPEC,
95 'vpnv6fs': RF_VPNv6_FLOWSPEC,
96 'l2vpnfs': RF_L2VPN_FLOWSPEC,
99 if addr_family not in rfs:
100 raise WrongParamError('Unknown or unsupported family: %s' %
103 rf = rfs.get(addr_family)
104 table_manager = self.get_core_service().table_manager
105 gtable = table_manager.get_global_table_by_route_family(rf)
106 if gtable is not None:
107 return [self._dst_to_dict(dst)
108 for dst in sorted(gtable.values())]
112 def _dst_to_dict(self, dst):
114 'prefix': dst.nlri_str}
116 def _path_to_dict(dst, path):
118 path_seg_list = path.get_pattr(BGP_ATTR_TYPE_AS_PATH).path_seg_list
120 if isinstance(path_seg_list, list):
122 for as_path_seg in path_seg_list:
123 for as_num in as_path_seg:
124 aspath.append(as_num)
128 origin = path.get_pattr(BGP_ATTR_TYPE_ORIGIN)
129 origin = origin.value if origin else None
131 if origin == BGP_ATTR_ORIGIN_IGP:
133 elif origin == BGP_ATTR_ORIGIN_EGP:
135 elif origin == BGP_ATTR_ORIGIN_INCOMPLETE:
138 nexthop = path.nexthop
139 # Get the MED path attribute
140 med = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC)
141 med = med.value if med else ''
142 # Get best path reason
143 bpr = dst.best_path_reason if path == dst.best_path else ''
145 # Get local preference
146 localpref = path.get_pattr(BGP_ATTR_TYPE_LOCAL_PREF)
147 localpref = localpref.value if localpref else ''
149 if hasattr(path.nlri, 'label_list'):
150 labels = path.nlri.label_list
154 return {'best': (path == dst.best_path),
156 'prefix': path.nlri_str,
162 'localpref': localpref}
164 for path in dst.known_path_list:
165 ret['paths'].append(_path_to_dict(dst, path))
169 def check_logging(self):
170 return self.log_handler and self._has_log_handler(self.log_handler)
172 def check_logging_level(self):
173 return logging.getLevelName(self.log_handler.level)
175 def _has_log_handler(self, log_handler):
176 if log_handler in logging.getLogger('bgpspeaker').handlers:
180 def route_refresh(self, peer_ip=None, afi=None, safi=None):
186 if afi is None and safi is None:
187 route_families.extend(SUPPORTED_GLOBAL_RF)
189 route_family = RouteFamily(afi, safi)
190 if route_family not in SUPPORTED_GLOBAL_RF:
191 raise WrongParamError('Not supported address-family'
192 ' %s, %s' % (afi, safi))
193 route_families.append(route_family)
195 pm = CORE_MANAGER.get_core_service().peer_manager
196 pm.make_route_refresh_request(peer_ip, *route_families)
197 except Exception as e:
198 LOG.error(traceback.format_exc())
199 raise WrongParamError(str(e))
202 def get_core_service(self):
203 return CORE_MANAGER.get_core_service()
206 @add_bgp_error_metadata(code=INTERNAL_API_ERROR,
207 sub_code=INTERNAL_API_SUB_ERROR,
208 def_desc='Unknown internal api exception.')
209 class WrongParamError(BGPSException):