1 # Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
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
7 # http://www.apache.org/licenses/LICENSE-2.0
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
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
17 Runtime configuration manager.
21 from ryu.services.protocols.bgp.api.base import register
22 from ryu.services.protocols.bgp.api.base import RegisterWithArgChecks
23 from ryu.services.protocols.bgp.api.base import FLOWSPEC_FAMILY
24 from ryu.services.protocols.bgp.api.base import FLOWSPEC_RULES
25 from ryu.services.protocols.bgp.api.base import FLOWSPEC_ACTIONS
26 from ryu.services.protocols.bgp.core_manager import CORE_MANAGER
27 from ryu.services.protocols.bgp.rtconf.base import ConfWithId
28 from ryu.services.protocols.bgp.rtconf.base import RuntimeConfigError
29 from ryu.services.protocols.bgp.rtconf import neighbors
30 from ryu.services.protocols.bgp.rtconf.neighbors import NeighborConf
31 from ryu.services.protocols.bgp.rtconf.vrfs import ROUTE_DISTINGUISHER
32 from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF
33 from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4
34 from ryu.services.protocols.bgp.rtconf.vrfs import VrfConf
35 from ryu.services.protocols.bgp import constants as const
37 LOG = logging.getLogger('bgpspeaker.api.rtconf')
40 # =============================================================================
41 # Neighbor configuration related APIs
42 # =============================================================================
45 def _get_neighbor_conf(neigh_ip_address):
46 """Returns neighbor configuration for given neighbor ip address.
48 Raises exception if no neighbor with `neigh_ip_address` exists.
51 CORE_MANAGER.neighbors_conf.get_neighbor_conf(neigh_ip_address)
53 raise RuntimeConfigError(desc='No Neighbor configuration with IP'
54 ' address %s' % neigh_ip_address)
55 assert isinstance(neigh_conf, NeighborConf)
59 @register(name='neighbor.create')
60 def create_neighbor(**kwargs):
61 neigh_conf = NeighborConf(**kwargs)
62 CORE_MANAGER.neighbors_conf.add_neighbor_conf(neigh_conf)
66 @RegisterWithArgChecks(name='neighbor.update_enabled',
67 req_args=[neighbors.IP_ADDRESS, neighbors.ENABLED])
68 def update_neighbor_enabled(neigh_ip_address, enabled):
69 neigh_conf = _get_neighbor_conf(neigh_ip_address)
70 neigh_conf.enabled = enabled
74 @RegisterWithArgChecks(name='neighbor.update',
75 req_args=[neighbors.IP_ADDRESS, neighbors.CHANGES])
76 def update_neighbor(neigh_ip_address, changes):
78 for k, v in changes.items():
79 if k == neighbors.MULTI_EXIT_DISC:
80 rets.append(_update_med(neigh_ip_address, v))
82 if k == neighbors.ENABLED:
83 rets.append(update_neighbor_enabled(neigh_ip_address, v))
85 if k == neighbors.CONNECT_MODE:
86 rets.append(_update_connect_mode(neigh_ip_address, v))
91 def _update_med(neigh_ip_address, value):
92 neigh_conf = _get_neighbor_conf(neigh_ip_address)
93 neigh_conf.multi_exit_disc = value
94 LOG.info('MED value for neigh: %s updated to %s', neigh_conf, value)
98 def _update_connect_mode(neigh_ip_address, value):
99 neigh_conf = _get_neighbor_conf(neigh_ip_address)
100 neigh_conf.connect_mode = value
104 @RegisterWithArgChecks(name='neighbor.delete',
105 req_args=[neighbors.IP_ADDRESS])
106 def delete_neighbor(neigh_ip_address):
107 neigh_conf = _get_neighbor_conf(neigh_ip_address)
109 neigh_conf.enabled = False
110 CORE_MANAGER.neighbors_conf.remove_neighbor_conf(neigh_ip_address)
115 @RegisterWithArgChecks(name='neighbor.get',
116 req_args=[neighbors.IP_ADDRESS])
117 def get_neighbor_conf(neigh_ip_address):
118 """Returns a neighbor configuration for given ip address if exists."""
119 neigh_conf = _get_neighbor_conf(neigh_ip_address)
120 return neigh_conf.settings
123 @register(name='neighbors.get')
124 def get_neighbors_conf():
125 return CORE_MANAGER.neighbors_conf.settings
128 @RegisterWithArgChecks(name='neighbor.in_filter.get',
129 req_args=[neighbors.IP_ADDRESS])
130 def get_neighbor_in_filter(neigh_ip_address):
131 """Returns a neighbor in_filter for given ip address if exists."""
132 core = CORE_MANAGER.get_core_service()
133 peer = core.peer_manager.get_by_addr(neigh_ip_address)
134 return peer.in_filters
137 @RegisterWithArgChecks(name='neighbor.in_filter.set',
138 req_args=[neighbors.IP_ADDRESS, neighbors.IN_FILTER])
139 def set_neighbor_in_filter(neigh_ip_address, filters):
140 """Returns a neighbor in_filter for given ip address if exists."""
141 core = CORE_MANAGER.get_core_service()
142 peer = core.peer_manager.get_by_addr(neigh_ip_address)
143 peer.in_filters = filters
147 @RegisterWithArgChecks(name='neighbor.out_filter.get',
148 req_args=[neighbors.IP_ADDRESS])
149 def get_neighbor_out_filter(neigh_ip_address):
150 """Returns a neighbor out_filter for given ip address if exists."""
151 core = CORE_MANAGER.get_core_service()
152 ret = core.peer_manager.get_by_addr(neigh_ip_address).out_filters
156 @RegisterWithArgChecks(name='neighbor.out_filter.set',
157 req_args=[neighbors.IP_ADDRESS, neighbors.OUT_FILTER])
158 def set_neighbor_out_filter(neigh_ip_address, filters):
159 """Sets the out_filter of a neighbor."""
160 core = CORE_MANAGER.get_core_service()
161 peer = core.peer_manager.get_by_addr(neigh_ip_address)
162 peer.out_filters = filters
166 @RegisterWithArgChecks(name='neighbor.attribute_map.set',
167 req_args=[neighbors.IP_ADDRESS,
168 neighbors.ATTRIBUTE_MAP],
169 opt_args=[ROUTE_DISTINGUISHER, VRF_RF])
170 def set_neighbor_attribute_map(neigh_ip_address, at_maps,
171 route_dist=None, route_family=VRF_RF_IPV4):
172 """set attribute_maps to the neighbor."""
173 core = CORE_MANAGER.get_core_service()
174 peer = core.peer_manager.get_by_addr(neigh_ip_address)
176 at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT
179 if route_dist is not None:
181 CORE_MANAGER.vrfs_conf.get_vrf_conf(route_dist, route_family)
183 at_maps_key = ':'.join([route_dist, route_family])
185 raise RuntimeConfigError(desc='No VrfConf with rd %s' %
188 at_maps_dict[const.ATTR_MAPS_LABEL_KEY] = at_maps_key
189 at_maps_dict[const.ATTR_MAPS_VALUE] = at_maps
190 peer.attribute_maps = at_maps_dict
195 @RegisterWithArgChecks(name='neighbor.attribute_map.get',
196 req_args=[neighbors.IP_ADDRESS],
197 opt_args=[ROUTE_DISTINGUISHER, VRF_RF])
198 def get_neighbor_attribute_map(neigh_ip_address, route_dist=None,
199 route_family=VRF_RF_IPV4):
200 """Returns a neighbor attribute_map for given ip address if exists."""
201 core = CORE_MANAGER.get_core_service()
202 peer = core.peer_manager.get_by_addr(neigh_ip_address)
203 at_maps_key = const.ATTR_MAPS_LABEL_DEFAULT
205 if route_dist is not None:
206 at_maps_key = ':'.join([route_dist, route_family])
207 at_maps = peer.attribute_maps.get(at_maps_key)
209 return at_maps.get(const.ATTR_MAPS_ORG_KEY)
213 # =============================================================================
214 # VRF configuration related APIs
215 # =============================================================================
218 @register(name='vrf.create')
219 def create_vrf(**kwargs):
220 vrf_conf = VrfConf(**kwargs)
221 CORE_MANAGER.vrfs_conf.add_vrf_conf(vrf_conf)
225 @register(name='vrf.update')
226 def update_vrf(**kwargs):
227 route_dist = kwargs.get(ROUTE_DISTINGUISHER)
228 vrf_id = kwargs.get(ConfWithId.ID)
229 vrf_rf = kwargs.get(VRF_RF)
230 vrf_conf = CORE_MANAGER.vrfs_conf.get_vrf_conf(
231 route_dist, vrf_rf, vrf_id=vrf_id
234 # If we do not have a VrfConf with given id, we create one.
238 vrf_conf.update(**kwargs)
242 @RegisterWithArgChecks(name='vrf.delete', req_args=[ROUTE_DISTINGUISHER])
243 def delete_vrf(route_dist):
244 vrf_conf = CORE_MANAGER.vrfs_conf.remove_vrf_conf(route_dist)
251 @RegisterWithArgChecks(
253 req_args=[ROUTE_DISTINGUISHER],
255 def get_vrf(route_dist, route_family=VRF_RF_IPV4):
256 vrf_conf = CORE_MANAGER.vrfs_conf.get_vrf_conf(
257 route_dist, vrf_rf=route_family
260 raise RuntimeConfigError(desc='No VrfConf with vpn id %s' %
262 return vrf_conf.settings
265 @register(name='vrfs.get')
267 vrfs_conf = CORE_MANAGER.vrfs_conf
268 return vrfs_conf.settings
270 # =============================================================================
271 # network configuration related APIs
272 # =============================================================================
275 @register(name='network.add')
276 def add_network(prefix, next_hop=None):
277 tm = CORE_MANAGER.get_core_service().table_manager
278 tm.update_global_table(prefix, next_hop)
282 @register(name='network.del')
283 def del_network(prefix):
284 tm = CORE_MANAGER.get_core_service().table_manager
285 tm.update_global_table(prefix, is_withdraw=True)
288 # =============================================================================
289 # BMP configuration related APIs
290 # =============================================================================
293 @register(name='bmp.start')
294 def bmp_start(host, port):
295 core = CORE_MANAGER.get_core_service()
296 return core.start_bmp(host, port)
299 @register(name='bmp.stop')
300 def bmp_stop(host, port):
301 core = CORE_MANAGER.get_core_service()
302 return core.stop_bmp(host, port)
305 # =============================================================================
306 # BGP Flow Specification Routes related APIs
307 # =============================================================================
309 @RegisterWithArgChecks(
311 req_args=[FLOWSPEC_FAMILY, FLOWSPEC_RULES],
312 opt_args=[FLOWSPEC_ACTIONS])
313 def add_flowspec(flowspec_family, rules, **kwargs):
314 tm = CORE_MANAGER.get_core_service().table_manager
315 tm.update_flowspec_global_table(flowspec_family, rules, **kwargs)
319 @RegisterWithArgChecks(
321 req_args=[FLOWSPEC_FAMILY, FLOWSPEC_RULES])
322 def del_flowspec(flowspec_family, rules):
323 tm = CORE_MANAGER.get_core_service().table_manager
324 tm.update_flowspec_global_table(flowspec_family, rules, is_withdraw=True)