~ubuntu-branches/ubuntu/wily/ryu/wily-proposed

« back to all changes in this revision

Viewing changes to ryu/services/protocols/bgp/operator/internal_api.py

  • Committer: Package Import Robot
  • Author(s): Dariusz Dwornikowski
  • Date: 2014-08-18 16:58:52 UTC
  • Revision ID: package-import@ubuntu.com-20140818165852-i0qck3g5mw7rtxt0
Tags: upstream-3.12
ImportĀ upstreamĀ versionĀ 3.12

Show diffs side-by-side

added added

removed removed

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