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 Running or runtime configuration related to bgp peers/neighbors.
19 from abc import abstractmethod
25 from ryu.lib import ip
27 from ryu.lib.packet.bgp import RF_IPv4_UC
28 from ryu.lib.packet.bgp import RF_IPv6_UC
29 from ryu.lib.packet.bgp import RF_IPv4_VPN
30 from ryu.lib.packet.bgp import RF_IPv6_VPN
31 from ryu.lib.packet.bgp import RF_L2_EVPN
32 from ryu.lib.packet.bgp import RF_IPv4_FLOWSPEC
33 from ryu.lib.packet.bgp import RF_IPv6_FLOWSPEC
34 from ryu.lib.packet.bgp import RF_VPNv4_FLOWSPEC
35 from ryu.lib.packet.bgp import RF_VPNv6_FLOWSPEC
36 from ryu.lib.packet.bgp import RF_L2VPN_FLOWSPEC
37 from ryu.lib.packet.bgp import RF_RTC_UC
38 from ryu.lib.packet.bgp import BGPOptParamCapabilityFourOctetAsNumber
39 from ryu.lib.packet.bgp import BGPOptParamCapabilityEnhancedRouteRefresh
40 from ryu.lib.packet.bgp import BGPOptParamCapabilityMultiprotocol
41 from ryu.lib.packet.bgp import BGPOptParamCapabilityRouteRefresh
42 from ryu.lib.packet.bgp import BGP_CAP_FOUR_OCTET_AS_NUMBER
43 from ryu.lib.packet.bgp import BGP_CAP_ENHANCED_ROUTE_REFRESH
44 from ryu.lib.packet.bgp import BGP_CAP_MULTIPROTOCOL
45 from ryu.lib.packet.bgp import BGP_CAP_ROUTE_REFRESH
47 from ryu.services.protocols.bgp.base import OrderedDict
48 from ryu.services.protocols.bgp.constants import STD_BGP_SERVER_PORT_NUM
49 from ryu.services.protocols.bgp.rtconf.base import ADVERTISE_PEER_AS
50 from ryu.services.protocols.bgp.rtconf.base import BaseConf
51 from ryu.services.protocols.bgp.rtconf.base import BaseConfListener
52 from ryu.services.protocols.bgp.rtconf.base import CAP_ENHANCED_REFRESH
53 from ryu.services.protocols.bgp.rtconf.base import CAP_FOUR_OCTET_AS_NUMBER
54 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4
55 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6
56 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4
57 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6
58 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_EVPN
59 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4FS
60 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6FS
61 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4FS
62 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6FS
63 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_L2VPNFS
64 from ryu.services.protocols.bgp.rtconf.base import CAP_REFRESH
65 from ryu.services.protocols.bgp.rtconf.base import CAP_RTC
66 from ryu.services.protocols.bgp.rtconf.base import compute_optional_conf
67 from ryu.services.protocols.bgp.rtconf.base import ConfigTypeError
68 from ryu.services.protocols.bgp.rtconf.base import ConfigValueError
69 from ryu.services.protocols.bgp.rtconf.base import ConfWithId
70 from ryu.services.protocols.bgp.rtconf.base import ConfWithIdListener
71 from ryu.services.protocols.bgp.rtconf.base import ConfWithStats
72 from ryu.services.protocols.bgp.rtconf.base import ConfWithStatsListener
73 from ryu.services.protocols.bgp.rtconf.base import HOLD_TIME
74 from ryu.services.protocols.bgp.rtconf.base import MAX_PREFIXES
75 from ryu.services.protocols.bgp.rtconf.base import MULTI_EXIT_DISC
76 from ryu.services.protocols.bgp.rtconf.base import RTC_AS
77 from ryu.services.protocols.bgp.rtconf.base import RuntimeConfigError
78 from ryu.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS
79 from ryu.services.protocols.bgp.rtconf.base import validate
80 from ryu.services.protocols.bgp.rtconf.base import validate_med
81 from ryu.services.protocols.bgp.rtconf.base import validate_soo_list
82 from ryu.services.protocols.bgp.utils.validation import is_valid_asn
83 from ryu.services.protocols.bgp.info_base.base import Filter
84 from ryu.services.protocols.bgp.info_base.base import PrefixFilter
85 from ryu.services.protocols.bgp.info_base.base import AttributeMap
87 LOG = logging.getLogger('bgpspeaker.rtconf.neighbor')
89 # Various neighbor settings.
90 REMOTE_AS = 'remote_as'
91 IP_ADDRESS = 'ip_address'
92 REMOTE_PORT = 'remote_port'
95 LOCAL_ADDRESS = 'local_address'
96 LOCAL_PORT = 'local_port'
98 PEER_NEXT_HOP = 'peer_next_hop'
100 IN_FILTER = 'in_filter'
101 OUT_FILTER = 'out_filter'
102 IS_ROUTE_SERVER_CLIENT = 'is_route_server_client'
103 IS_ROUTE_REFLECTOR_CLIENT = 'is_route_reflector_client'
104 CHECK_FIRST_AS = 'check_first_as'
105 ATTRIBUTE_MAP = 'attribute_map'
106 IS_NEXT_HOP_SELF = 'is_next_hop_self'
107 CONNECT_MODE = 'connect_mode'
108 CONNECT_MODE_ACTIVE = 'active'
109 CONNECT_MODE_PASSIVE = 'passive'
110 CONNECT_MODE_BOTH = 'both'
112 # Default value constants.
113 DEFAULT_BGP_PORT = STD_BGP_SERVER_PORT_NUM
114 DEFAULT_CAP_GR_NULL = True
115 DEFAULT_CAP_REFRESH = True
116 DEFAULT_CAP_ENHANCED_REFRESH = False
117 DEFAULT_CAP_FOUR_OCTET_AS_NUMBER = True
118 DEFAULT_CAP_MBGP_IPV4 = True
119 DEFAULT_CAP_MBGP_IPV6 = False
120 DEFAULT_CAP_MBGP_VPNV4 = False
121 DEFAULT_CAP_MBGP_VPNV6 = False
122 DEFAULT_CAP_MBGP_EVPN = False
123 DEFAULT_CAP_MBGP_IPV4FS = False
124 DEFAULT_CAP_MBGP_IPV6FS = False
125 DEFAULT_CAP_MBGP_VPNV4FS = False
126 DEFAULT_CAP_MBGP_VPNV6FS = False
127 DEFAULT_CAP_MBGP_L2VPNFS = False
128 DEFAULT_HOLD_TIME = 40
129 DEFAULT_ENABLED = True
130 DEFAULT_CAP_RTC = False
131 DEFAULT_IN_FILTER = []
132 DEFAULT_OUT_FILTER = []
133 DEFAULT_IS_ROUTE_SERVER_CLIENT = False
134 DEFAULT_IS_ROUTE_REFLECTOR_CLIENT = False
135 DEFAULT_CHECK_FIRST_AS = False
136 DEFAULT_IS_NEXT_HOP_SELF = False
137 DEFAULT_CONNECT_MODE = CONNECT_MODE_BOTH
139 # Default value for *MAX_PREFIXES* setting is set to 0.
140 DEFAULT_MAX_PREFIXES = 0
141 DEFAULT_ADVERTISE_PEER_AS = False
144 @validate(name=ENABLED)
145 def validate_enabled(enabled):
146 if not isinstance(enabled, bool):
147 raise ConfigValueError(desc='Enable property is not an instance of '
152 @validate(name=CHANGES)
153 def validate_changes(changes):
154 for k, v in changes.items():
155 if k not in (MULTI_EXIT_DISC, ENABLED, CONNECT_MODE):
156 raise ConfigValueError(desc="Unknown field to change: %s" % k)
158 if k == MULTI_EXIT_DISC:
162 elif k == CONNECT_MODE:
163 validate_connect_mode(v)
167 def valid_ip_address(addr):
168 if not ip.valid_ipv4(addr) and not ip.valid_ipv6(addr):
173 @validate(name=IP_ADDRESS)
174 def validate_ip_address(ip_address):
175 if not valid_ip_address(ip_address):
176 raise ConfigValueError(desc='Invalid neighbor ip_address: %s' %
178 return str(netaddr.IPAddress(ip_address))
181 @validate(name=LOCAL_ADDRESS)
182 def validate_local_address(ip_address):
183 if not valid_ip_address(ip_address):
184 raise ConfigValueError(desc='Invalid local ip_address: %s' %
186 return str(netaddr.IPAddress(ip_address))
189 @validate(name=PEER_NEXT_HOP)
190 def validate_next_hop(ip_address):
191 if not valid_ip_address(ip_address):
192 raise ConfigValueError(desc='Invalid next_hop ip_address: %s' %
194 return str(netaddr.IPAddress(ip_address))
197 @validate(name=PASSWORD)
198 def validate_password(password):
202 @validate(name=LOCAL_PORT)
203 def validate_local_port(port):
204 if not isinstance(port, numbers.Integral):
205 raise ConfigTypeError(desc='Invalid local port: %s' % port)
206 if port < 1025 or port > 65535:
207 raise ConfigValueError(desc='Invalid local port value: %s, has to be'
208 ' between 1025 and 65535' % port)
212 @validate(name=REMOTE_AS)
213 def validate_remote_as(asn):
214 if not is_valid_asn(asn):
215 raise ConfigValueError(desc='Invalid remote as value %s' % asn)
219 @validate(name=REMOTE_PORT)
220 def validate_remote_port(port):
221 if not isinstance(port, numbers.Integral):
222 raise ConfigTypeError(desc='Invalid remote port: %s' % port)
226 def valid_prefix_filter(filter_):
227 policy = filter_.get('policy', None)
228 if policy == 'permit':
229 policy = PrefixFilter.POLICY_PERMIT
231 policy = PrefixFilter.POLICY_DENY
232 prefix = filter_['prefix']
233 ge = filter_.get('ge', None)
234 le = filter_.get('le', None)
235 return PrefixFilter(prefix, policy, ge=ge, le=le)
238 PREFIX_FILTER = 'prefix_filter'
240 SUPPORTED_FILTER_VALIDATORS = {
241 PREFIX_FILTER: valid_prefix_filter
245 def valid_filter(filter_):
246 if isinstance(filter_, Filter):
249 if not isinstance(filter_, dict):
250 raise ConfigTypeError(desc='Invalid filter: %s' % filter_)
252 if 'type' not in filter_:
253 raise ConfigTypeError(desc='Invalid filter: %s, needs \'type\' field'
256 if not filter_['type'] in SUPPORTED_FILTER_VALIDATORS:
257 raise ConfigTypeError(desc='Invalid filter type: %s, supported filter'
260 list(SUPPORTED_FILTER_VALIDATORS.keys())))
262 return SUPPORTED_FILTER_VALIDATORS[filter_['type']](filter_)
265 def valid_attribute_map(attribute_map):
266 if not isinstance(attribute_map, AttributeMap):
267 raise ConfigTypeError(desc='Invalid AttributeMap: %s' % attribute_map)
272 @validate(name=IN_FILTER)
273 def validate_in_filters(filters):
274 return [valid_filter(filter_) for filter_ in filters]
277 @validate(name=OUT_FILTER)
278 def validate_out_filters(filters):
279 return [valid_filter(filter_) for filter_ in filters]
282 @validate(name=ATTRIBUTE_MAP)
283 def validate_attribute_maps(attribute_maps):
284 return [valid_attribute_map(attribute_map)
285 for attribute_map in attribute_maps]
288 @validate(name=IS_ROUTE_SERVER_CLIENT)
289 def validate_is_route_server_client(is_route_server_client):
290 if not isinstance(is_route_server_client, bool):
291 raise ConfigValueError(desc='Invalid is_route_server_client(%s)' %
292 is_route_server_client)
294 return is_route_server_client
297 @validate(name=IS_ROUTE_REFLECTOR_CLIENT)
298 def validate_is_route_reflector_client(is_route_reflector_client):
299 if not isinstance(is_route_reflector_client, bool):
300 raise ConfigValueError(desc='Invalid is_route_reflector_client(%s)' %
301 is_route_reflector_client)
303 return is_route_reflector_client
306 @validate(name=CHECK_FIRST_AS)
307 def validate_check_first_as(check_first_as):
308 if not isinstance(check_first_as, bool):
309 raise ConfigValueError(desc='Invalid check_first_as(%s)' %
312 return check_first_as
315 @validate(name=IS_NEXT_HOP_SELF)
316 def validate_is_next_hop_self(is_next_hop_self):
317 if not isinstance(is_next_hop_self, bool):
318 raise ConfigValueError(desc='Invalid is_next_hop_self(%s)' %
321 return is_next_hop_self
324 @validate(name=CONNECT_MODE)
325 def validate_connect_mode(mode):
326 if mode not in (CONNECT_MODE_ACTIVE,
327 CONNECT_MODE_PASSIVE,
329 raise ConfigValueError(desc='Invalid connect_mode(%s)' % mode)
333 class NeighborConf(ConfWithId, ConfWithStats):
334 """Class that encapsulates one neighbors' configuration."""
336 UPDATE_ENABLED_EVT = 'update_enabled_evt'
337 UPDATE_MED_EVT = 'update_med_evt'
338 UPDATE_CONNECT_MODE_EVT = 'update_connect_mode_evt'
340 VALID_EVT = frozenset([UPDATE_ENABLED_EVT, UPDATE_MED_EVT,
341 UPDATE_CONNECT_MODE_EVT])
342 REQUIRED_SETTINGS = frozenset([REMOTE_AS, IP_ADDRESS])
343 OPTIONAL_SETTINGS = frozenset([CAP_REFRESH,
344 CAP_ENHANCED_REFRESH,
345 CAP_FOUR_OCTET_AS_NUMBER,
346 CAP_MBGP_IPV4, CAP_MBGP_IPV6,
347 CAP_MBGP_VPNV4, CAP_MBGP_VPNV6,
348 CAP_RTC, CAP_MBGP_EVPN,
349 CAP_MBGP_IPV4FS, CAP_MBGP_VPNV4FS,
350 CAP_MBGP_IPV6FS, CAP_MBGP_VPNV6FS,
352 RTC_AS, HOLD_TIME, REMOTE_PORT,
353 ENABLED, MULTI_EXIT_DISC, MAX_PREFIXES,
354 ADVERTISE_PEER_AS, SITE_OF_ORIGINS,
355 LOCAL_ADDRESS, LOCAL_PORT, LOCAL_AS,
356 PEER_NEXT_HOP, PASSWORD,
357 IN_FILTER, OUT_FILTER,
358 IS_ROUTE_SERVER_CLIENT,
359 IS_ROUTE_REFLECTOR_CLIENT,
361 IS_NEXT_HOP_SELF, CONNECT_MODE])
363 def __init__(self, **kwargs):
364 super(NeighborConf, self).__init__(**kwargs)
366 def _init_opt_settings(self, **kwargs):
367 self._settings[CAP_REFRESH] = compute_optional_conf(
368 CAP_REFRESH, DEFAULT_CAP_REFRESH, **kwargs)
369 self._settings[CAP_ENHANCED_REFRESH] = compute_optional_conf(
370 CAP_ENHANCED_REFRESH, DEFAULT_CAP_ENHANCED_REFRESH, **kwargs)
371 self._settings[CAP_FOUR_OCTET_AS_NUMBER] = compute_optional_conf(
372 CAP_FOUR_OCTET_AS_NUMBER,
373 DEFAULT_CAP_FOUR_OCTET_AS_NUMBER, **kwargs)
374 self._settings[CAP_MBGP_IPV4] = compute_optional_conf(
375 CAP_MBGP_IPV4, DEFAULT_CAP_MBGP_IPV4, **kwargs)
376 self._settings[CAP_MBGP_IPV6] = compute_optional_conf(
377 CAP_MBGP_IPV6, DEFAULT_CAP_MBGP_IPV6, **kwargs)
378 self._settings[CAP_MBGP_VPNV4] = compute_optional_conf(
379 CAP_MBGP_VPNV4, DEFAULT_CAP_MBGP_VPNV4, **kwargs)
380 self._settings[CAP_MBGP_EVPN] = compute_optional_conf(
381 CAP_MBGP_EVPN, DEFAULT_CAP_MBGP_EVPN, **kwargs)
382 self._settings[CAP_MBGP_VPNV6] = compute_optional_conf(
383 CAP_MBGP_VPNV6, DEFAULT_CAP_MBGP_VPNV6, **kwargs)
384 self._settings[CAP_MBGP_IPV4FS] = compute_optional_conf(
385 CAP_MBGP_IPV4FS, DEFAULT_CAP_MBGP_IPV4FS, **kwargs)
386 self._settings[CAP_MBGP_IPV6FS] = compute_optional_conf(
387 CAP_MBGP_IPV6FS, DEFAULT_CAP_MBGP_IPV6FS, **kwargs)
388 self._settings[CAP_MBGP_VPNV4FS] = compute_optional_conf(
389 CAP_MBGP_VPNV4FS, DEFAULT_CAP_MBGP_VPNV4FS, **kwargs)
390 self._settings[CAP_MBGP_VPNV6FS] = compute_optional_conf(
391 CAP_MBGP_VPNV6FS, DEFAULT_CAP_MBGP_VPNV6FS, **kwargs)
392 self._settings[CAP_MBGP_L2VPNFS] = compute_optional_conf(
393 CAP_MBGP_L2VPNFS, DEFAULT_CAP_MBGP_L2VPNFS, **kwargs)
394 self._settings[HOLD_TIME] = compute_optional_conf(
395 HOLD_TIME, DEFAULT_HOLD_TIME, **kwargs)
396 self._settings[ENABLED] = compute_optional_conf(
397 ENABLED, DEFAULT_ENABLED, **kwargs)
398 self._settings[MAX_PREFIXES] = compute_optional_conf(
399 MAX_PREFIXES, DEFAULT_MAX_PREFIXES, **kwargs)
400 self._settings[ADVERTISE_PEER_AS] = compute_optional_conf(
401 ADVERTISE_PEER_AS, DEFAULT_ADVERTISE_PEER_AS, **kwargs)
402 self._settings[IN_FILTER] = compute_optional_conf(
403 IN_FILTER, DEFAULT_IN_FILTER, **kwargs)
404 self._settings[OUT_FILTER] = compute_optional_conf(
405 OUT_FILTER, DEFAULT_OUT_FILTER, **kwargs)
406 self._settings[IS_ROUTE_SERVER_CLIENT] = compute_optional_conf(
407 IS_ROUTE_SERVER_CLIENT,
408 DEFAULT_IS_ROUTE_SERVER_CLIENT, **kwargs)
409 self._settings[IS_ROUTE_REFLECTOR_CLIENT] = compute_optional_conf(
410 IS_ROUTE_REFLECTOR_CLIENT,
411 DEFAULT_IS_ROUTE_REFLECTOR_CLIENT, **kwargs)
412 self._settings[CHECK_FIRST_AS] = compute_optional_conf(
413 CHECK_FIRST_AS, DEFAULT_CHECK_FIRST_AS, **kwargs)
414 self._settings[IS_NEXT_HOP_SELF] = compute_optional_conf(
416 DEFAULT_IS_NEXT_HOP_SELF, **kwargs)
417 self._settings[CONNECT_MODE] = compute_optional_conf(
418 CONNECT_MODE, DEFAULT_CONNECT_MODE, **kwargs)
419 self._settings[REMOTE_PORT] = compute_optional_conf(
420 REMOTE_PORT, DEFAULT_BGP_PORT, **kwargs)
422 # We do not have valid default MED value.
423 # If no MED attribute is provided then we do not have to use MED.
424 # If MED attribute is provided we have to validate it and use it.
425 med = kwargs.pop(MULTI_EXIT_DISC, None)
426 if med and validate_med(med):
427 self._settings[MULTI_EXIT_DISC] = med
429 # We do not have valid default SOO value.
430 # If no SOO attribute is provided then we do not have to use SOO.
431 # If SOO attribute is provided we have to validate it and use it.
432 soos = kwargs.pop(SITE_OF_ORIGINS, None)
433 if soos and validate_soo_list(soos):
434 self._settings[SITE_OF_ORIGINS] = soos
436 # We do not have valid default LOCAL_ADDRESS and LOCAL_PORT value.
437 # If no LOCAL_ADDRESS/PORT is provided then we will bind to system
439 self._settings[LOCAL_ADDRESS] = compute_optional_conf(
440 LOCAL_ADDRESS, None, **kwargs)
441 self._settings[LOCAL_PORT] = compute_optional_conf(
442 LOCAL_PORT, None, **kwargs)
444 # We use the global defined local (router) AS as the default
446 from ryu.services.protocols.bgp.core_manager import CORE_MANAGER
447 g_local_as = CORE_MANAGER.common_conf.local_as
448 self._settings[LOCAL_AS] = compute_optional_conf(
449 LOCAL_AS, g_local_as, **kwargs)
451 self._settings[PEER_NEXT_HOP] = compute_optional_conf(
452 PEER_NEXT_HOP, None, **kwargs)
454 self._settings[PASSWORD] = compute_optional_conf(
455 PASSWORD, None, **kwargs)
457 # RTC configurations.
458 self._settings[CAP_RTC] = compute_optional_conf(
459 CAP_RTC, DEFAULT_CAP_RTC, **kwargs)
460 # Default RTC_AS is local (router) AS.
461 self._settings[RTC_AS] = compute_optional_conf(
462 RTC_AS, g_local_as, **kwargs)
464 # Since ConfWithId' default values use str(self) and repr(self), we
465 # call super method after we have initialized other settings.
466 super(NeighborConf, self)._init_opt_settings(**kwargs)
469 def get_opt_settings(cls):
470 self_confs = super(NeighborConf, cls).get_opt_settings()
471 self_confs.update(NeighborConf.OPTIONAL_SETTINGS)
475 def get_req_settings(cls):
476 self_confs = super(NeighborConf, cls).get_req_settings()
477 self_confs.update(NeighborConf.REQUIRED_SETTINGS)
481 def get_valid_evts(cls):
482 self_valid_evts = super(NeighborConf, cls).get_valid_evts()
483 self_valid_evts.update(NeighborConf.VALID_EVT)
484 return self_valid_evts
486 # =========================================================================
487 # Required attributes
488 # =========================================================================
492 return self._settings[REMOTE_AS]
495 def ip_address(self):
496 return self._settings[IP_ADDRESS]
500 return self._settings[REMOTE_PORT]
503 def host_bind_ip(self):
504 return self._settings[LOCAL_ADDRESS]
507 def host_bind_port(self):
508 return self._settings[LOCAL_PORT]
512 return self._settings[PEER_NEXT_HOP]
516 return self._settings[PASSWORD]
518 # =========================================================================
519 # Optional attributes with valid defaults.
520 # =========================================================================
524 return self._settings[LOCAL_AS]
528 return self._settings[HOLD_TIME]
531 def cap_refresh(self):
532 return self._settings[CAP_REFRESH]
535 def cap_enhanced_refresh(self):
536 return self._settings[CAP_ENHANCED_REFRESH]
539 def cap_four_octet_as_number(self):
540 return self._settings[CAP_FOUR_OCTET_AS_NUMBER]
542 @cap_four_octet_as_number.setter
543 def cap_four_octet_as_number(self, cap):
544 kwargs = {CAP_FOUR_OCTET_AS_NUMBER: cap}
545 self._settings[CAP_FOUR_OCTET_AS_NUMBER] = compute_optional_conf(
546 CAP_FOUR_OCTET_AS_NUMBER,
547 DEFAULT_CAP_FOUR_OCTET_AS_NUMBER, **kwargs)
550 def cap_mbgp_ipv4(self):
551 return self._settings[CAP_MBGP_IPV4]
554 def cap_mbgp_ipv6(self):
555 return self._settings[CAP_MBGP_IPV6]
558 def cap_mbgp_vpnv4(self):
559 return self._settings[CAP_MBGP_VPNV4]
562 def cap_mbgp_vpnv6(self):
563 return self._settings[CAP_MBGP_VPNV6]
566 def cap_mbgp_evpn(self):
567 return self._settings[CAP_MBGP_EVPN]
570 def cap_mbgp_ipv4fs(self):
571 return self._settings[CAP_MBGP_IPV4FS]
574 def cap_mbgp_ipv6fs(self):
575 return self._settings[CAP_MBGP_IPV6FS]
578 def cap_mbgp_vpnv4fs(self):
579 return self._settings[CAP_MBGP_VPNV4FS]
582 def cap_mbgp_vpnv6fs(self):
583 return self._settings[CAP_MBGP_VPNV6FS]
586 def cap_mbgp_l2vpnfs(self):
587 return self._settings[CAP_MBGP_L2VPNFS]
591 return self._settings[CAP_RTC]
595 return self._settings[ENABLED]
598 def enabled(self, enable):
599 # Update enabled flag and notify listeners.
600 if self._settings[ENABLED] != enable:
601 self._settings[ENABLED] = enable
602 self._notify_listeners(NeighborConf.UPDATE_ENABLED_EVT,
605 # =========================================================================
606 # Optional attributes with no valid defaults.
607 # =========================================================================
610 def multi_exit_disc(self):
611 # This property does not have any valid default. Hence if not set we
613 return self._settings.get(MULTI_EXIT_DISC)
615 @multi_exit_disc.setter
616 def multi_exit_disc(self, value):
617 if self._settings.get(MULTI_EXIT_DISC) != value:
618 self._settings[MULTI_EXIT_DISC] = value
619 self._notify_listeners(NeighborConf.UPDATE_MED_EVT, value)
623 soos = self._settings.get(SITE_OF_ORIGINS)
632 return self._settings[RTC_AS]
636 return self._settings[IN_FILTER]
639 def out_filter(self):
640 return self._settings[OUT_FILTER]
643 def is_route_server_client(self):
644 return self._settings[IS_ROUTE_SERVER_CLIENT]
647 def is_route_reflector_client(self):
648 return self._settings[IS_ROUTE_REFLECTOR_CLIENT]
651 def check_first_as(self):
652 return self._settings[CHECK_FIRST_AS]
655 def is_next_hop_self(self):
656 return self._settings[IS_NEXT_HOP_SELF]
659 def connect_mode(self):
660 return self._settings[CONNECT_MODE]
663 def connect_mode(self, mode):
664 self._settings[CONNECT_MODE] = mode
665 self._notify_listeners(NeighborConf.UPDATE_CONNECT_MODE_EVT, mode)
667 def exceeds_max_prefix_allowed(self, prefix_count):
668 allowed_max = self._settings[MAX_PREFIXES]
670 # Check if allowed max. is unlimited.
672 # If max. prefix is limited, check if given exceeds this limit.
673 if prefix_count > allowed_max:
678 def get_configured_capabilities(self):
679 """Returns configured capabilities."""
681 capabilities = OrderedDict()
683 if self.cap_mbgp_ipv4:
685 BGPOptParamCapabilityMultiprotocol(
686 RF_IPv4_UC.afi, RF_IPv4_UC.safi))
688 if self.cap_mbgp_ipv6:
690 BGPOptParamCapabilityMultiprotocol(
691 RF_IPv6_UC.afi, RF_IPv6_UC.safi))
693 if self.cap_mbgp_vpnv4:
695 BGPOptParamCapabilityMultiprotocol(
696 RF_IPv4_VPN.afi, RF_IPv4_VPN.safi))
698 if self.cap_mbgp_vpnv6:
700 BGPOptParamCapabilityMultiprotocol(
701 RF_IPv6_VPN.afi, RF_IPv6_VPN.safi))
705 BGPOptParamCapabilityMultiprotocol(
706 RF_RTC_UC.afi, RF_RTC_UC.safi))
708 if self.cap_mbgp_evpn:
710 BGPOptParamCapabilityMultiprotocol(
711 RF_L2_EVPN.afi, RF_L2_EVPN.safi))
713 if self.cap_mbgp_ipv4fs:
715 BGPOptParamCapabilityMultiprotocol(
716 RF_IPv4_FLOWSPEC.afi, RF_IPv4_FLOWSPEC.safi))
718 if self.cap_mbgp_ipv6fs:
720 BGPOptParamCapabilityMultiprotocol(
721 RF_IPv6_FLOWSPEC.afi, RF_IPv6_FLOWSPEC.safi))
723 if self.cap_mbgp_vpnv4fs:
725 BGPOptParamCapabilityMultiprotocol(
726 RF_VPNv4_FLOWSPEC.afi, RF_VPNv4_FLOWSPEC.safi))
728 if self.cap_mbgp_vpnv6fs:
730 BGPOptParamCapabilityMultiprotocol(
731 RF_VPNv6_FLOWSPEC.afi, RF_VPNv6_FLOWSPEC.safi))
733 if self.cap_mbgp_l2vpnfs:
735 BGPOptParamCapabilityMultiprotocol(
736 RF_L2VPN_FLOWSPEC.afi, RF_L2VPN_FLOWSPEC.safi))
739 capabilities[BGP_CAP_MULTIPROTOCOL] = mbgp_caps
742 capabilities[BGP_CAP_ROUTE_REFRESH] = [
743 BGPOptParamCapabilityRouteRefresh()]
745 if self.cap_enhanced_refresh:
746 capabilities[BGP_CAP_ENHANCED_ROUTE_REFRESH] = [
747 BGPOptParamCapabilityEnhancedRouteRefresh()]
749 if self.cap_four_octet_as_number:
750 capabilities[BGP_CAP_FOUR_OCTET_AS_NUMBER] = [
751 BGPOptParamCapabilityFourOctetAsNumber(self.local_as)]
756 return '<%s(%r, %r, %r)>' % (self.__class__.__name__,
762 return 'Neighbor: %s' % self.ip_address
765 class NeighborsConf(BaseConf):
766 """Container of all neighbor configurations."""
768 ADD_NEIGH_CONF_EVT = 'add_neigh_conf_evt'
769 REMOVE_NEIGH_CONF_EVT = 'remove_neigh_conf_evt'
771 VALID_EVT = frozenset([ADD_NEIGH_CONF_EVT, REMOVE_NEIGH_CONF_EVT])
774 super(NeighborsConf, self).__init__()
777 def _init_opt_settings(self, **kwargs):
780 def update(self, **kwargs):
781 raise NotImplementedError('Use either add/remove_neighbor_conf'
785 def rtc_as_set(self):
786 """Returns current RTC AS configured for current neighbors.
789 for neigh in self._neighbors.values():
790 rtc_as_set.add(neigh.rtc_as)
794 def get_valid_evts(cls):
795 self_valid_evts = super(NeighborsConf, cls).get_valid_evts()
796 self_valid_evts.update(NeighborsConf.VALID_EVT)
797 return self_valid_evts
799 def add_neighbor_conf(self, neigh_conf):
800 # Check if we already know this neighbor
801 if neigh_conf.ip_address in self._neighbors.keys():
802 message = 'Neighbor with given ip address already exists'
803 raise RuntimeConfigError(desc=message)
805 # Add this neighbor to known configured neighbors and generate update
807 self._neighbors[neigh_conf.ip_address] = neigh_conf
808 self._notify_listeners(NeighborsConf.ADD_NEIGH_CONF_EVT, neigh_conf)
810 def remove_neighbor_conf(self, neigh_ip_address):
811 neigh_conf = self._neighbors.pop(neigh_ip_address, None)
813 raise RuntimeConfigError(desc='Tried to remove a neighbor that '
816 self._notify_listeners(NeighborsConf.REMOVE_NEIGH_CONF_EVT,
820 def get_neighbor_conf(self, neigh_ip_address):
821 return self._neighbors.get(neigh_ip_address, None)
824 return '<%s(%r)>' % (self.__class__.__name__, self._neighbors)
827 return '\'Neighbors\': %s' % self._neighbors
831 return [neighbor.settings for _, neighbor in
832 self._neighbors.items()]
835 class NeighborConfListener(ConfWithIdListener, ConfWithStatsListener):
836 """Base listener for change events to a specific neighbors' configurations.
839 def __init__(self, neigh_conf):
840 super(NeighborConfListener, self).__init__(neigh_conf)
841 neigh_conf.add_listener(NeighborConf.UPDATE_ENABLED_EVT,
842 self.on_update_enabled)
843 neigh_conf.add_listener(NeighborConf.UPDATE_MED_EVT,
845 neigh_conf.add_listener(NeighborConf.UPDATE_CONNECT_MODE_EVT,
846 self.on_update_connect_mode)
849 def on_update_enabled(self, evt):
850 raise NotImplementedError('This method should be overridden.')
853 def on_update_med(self, evt):
854 raise NotImplementedError('This method should be overridden.')
857 def on_update_connect_mode(self, evt):
858 raise NotImplementedError('This method should be overridden.')
861 class NeighborsConfListener(BaseConfListener):
862 """Base listener for change events to neighbor configuration container."""
864 def __init__(self, neighbors_conf):
865 super(NeighborsConfListener, self).__init__(neighbors_conf)
866 neighbors_conf.add_listener(NeighborsConf.ADD_NEIGH_CONF_EVT,
867 self.on_add_neighbor_conf)
868 neighbors_conf.add_listener(NeighborsConf.REMOVE_NEIGH_CONF_EVT,
869 self.on_remove_neighbor_conf)
872 def on_add_neighbor_conf(self, evt):
873 raise NotImplementedError('This method should be overridden.')
876 def on_remove_neighbor_conf(self, evt):
877 raise NotImplementedError('This method should be overridden.')