backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / bgp / info_base / vpn.py
1 # Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 """
17  Defines base data types and models required specifically for VPN support.
18 """
19
20 import abc
21 import logging
22 import six
23
24 from ryu.lib.packet.bgp import RF_L2_EVPN
25 from ryu.services.protocols.bgp.info_base.base import Destination
26 from ryu.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin
27 from ryu.services.protocols.bgp.info_base.base import Path
28 from ryu.services.protocols.bgp.info_base.base import Table
29
30 LOG = logging.getLogger('bgpspeaker.info_base.vpn')
31
32
33 class VpnTable(Table):
34     """Global table to store VPNv4 routing information.
35
36     Uses `VpnvXDest` to store destination information for each known vpnvX
37     paths.
38     """
39     ROUTE_FAMILY = None
40     VPN_DEST_CLASS = None
41
42     def __init__(self, core_service, signal_bus):
43         super(VpnTable, self).__init__(None, core_service, signal_bus)
44
45     def _table_key(self, vpn_nlri):
46         """Return a key that will uniquely identify this vpnvX NLRI inside
47         this table.
48         """
49         return vpn_nlri.route_dist + ':' + vpn_nlri.prefix
50
51     def _create_dest(self, nlri):
52         return self.VPN_DEST_CLASS(self, nlri)
53
54     def __str__(self):
55         return '%s(scope_id: %s, rf: %s)' % (
56             self.__class__.__name__, self.scope_id, self.route_family
57         )
58
59
60 @six.add_metaclass(abc.ABCMeta)
61 class VpnPath(Path):
62     ROUTE_FAMILY = None
63     VRF_PATH_CLASS = None
64     NLRI_CLASS = None
65
66     def clone_to_vrf(self, is_withdraw=False):
67         if self.ROUTE_FAMILY == RF_L2_EVPN:
68             # Because NLRI class is the same if the route family is EVPN,
69             # we re-use the NLRI instance.
70             vrf_nlri = self._nlri
71         else:  # self.ROUTE_FAMILY in [RF_IPv4_VPN, RF_IPv46_VPN]
72             vrf_nlri = self.NLRI_CLASS(self._nlri.prefix)
73
74         pathattrs = None
75         if not is_withdraw:
76             pathattrs = self.pathattr_map
77
78         vrf_path = self.VRF_PATH_CLASS(
79             puid=self.VRF_PATH_CLASS.create_puid(
80                 self._nlri.route_dist,
81                 self._nlri.prefix),
82             source=self.source,
83             nlri=vrf_nlri,
84             src_ver_num=self.source_version_num,
85             pattrs=pathattrs,
86             nexthop=self.nexthop,
87             is_withdraw=is_withdraw,
88             label_list=self._nlri.label_list)
89
90         return vrf_path
91
92
93 @six.add_metaclass(abc.ABCMeta)
94 class VpnDest(Destination, NonVrfPathProcessingMixin):
95     """Base class for VPN destinations."""
96
97     def _best_path_lost(self):
98         old_best_path = self._best_path
99         NonVrfPathProcessingMixin._best_path_lost(self)
100         self._core_service._signal_bus.best_path_changed(old_best_path, True)
101
102         # Best-path might have been imported into VRF tables, we have to
103         # withdraw from them, if the source is a peer.
104         if old_best_path:
105             withdraw_clone = old_best_path.clone(for_withdrawal=True)
106             tm = self._core_service.table_manager
107             tm.import_single_vpn_path_to_all_vrfs(
108                 withdraw_clone, path_rts=old_best_path.get_rts()
109             )
110
111     def _new_best_path(self, best_path):
112         NonVrfPathProcessingMixin._new_best_path(self, best_path)
113         self._core_service._signal_bus.best_path_changed(best_path, False)
114
115         # Extranet feature requires that we import new best path into VRFs.
116         tm = self._core_service.table_manager
117         tm.import_single_vpn_path_to_all_vrfs(
118             self._best_path, self._best_path.get_rts())