diff options
author | ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp> | 2014-04-16 04:13:39 +0000 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-04-17 08:38:43 +0900 |
commit | 9d5e66fa4e49ce66103dbc9640a33bd9c22fab3f (patch) | |
tree | 4e3ffe5f64c87372b27b0a4e795b0c02d3e534dc | |
parent | bdad6267de53a14115a84961fa075380dfcd34d5 (diff) |
bgp: use ryu bgp packet library instead of original one
Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
26 files changed, 568 insertions, 479 deletions
diff --git a/ryu/services/protocols/bgp/api/core.py b/ryu/services/protocols/bgp/api/core.py index b90ff897..d8ee1444 100644 --- a/ryu/services/protocols/bgp/api/core.py +++ b/ryu/services/protocols/bgp/api/core.py @@ -79,9 +79,9 @@ def reset_neighor(ip_address): return True -#============================================================================== +# ============================================================================= # Common configuration related APIs -#============================================================================== +# ============================================================================= @register(name='comm_conf.get') def get_common_conf(): diff --git a/ryu/services/protocols/bgp/api/rtconf.py b/ryu/services/protocols/bgp/api/rtconf.py index 98f51d9d..bca6cc78 100644 --- a/ryu/services/protocols/bgp/api/rtconf.py +++ b/ryu/services/protocols/bgp/api/rtconf.py @@ -33,9 +33,9 @@ from ryu.services.protocols.bgp.rtconf.vrfs import VrfConf LOG = logging.getLogger('bgpspeaker.api.rtconf') -#============================================================================== +# ============================================================================= # Neighbor configuration related APIs -#============================================================================== +# ============================================================================= def _get_neighbor_conf(neigh_ip_address): @@ -112,9 +112,9 @@ def get_neighbors_conf(): return CORE_MANAGER.neighbors_conf.settings -#============================================================================== +# ============================================================================= # VRF configuration related APIs -#============================================================================== +# ============================================================================= @register(name='vrf.create') def create_vrf(**kwargs): @@ -168,9 +168,9 @@ def get_vrfs_conf(): vrfs_conf = CORE_MANAGER.vrfs_conf return vrfs_conf.settings -#============================================================================== +# ============================================================================= # network configuration related APIs -#============================================================================== +# ============================================================================= @register(name='network.add') diff --git a/ryu/services/protocols/bgp/base.py b/ryu/services/protocols/bgp/base.py index 489ba3af..85795c5b 100644 --- a/ryu/services/protocols/bgp/base.py +++ b/ryu/services/protocols/bgp/base.py @@ -23,7 +23,11 @@ import traceback import weakref from eventlet.timeout import Timeout -from ryu.services.protocols.bgp.protocols.bgp import nlri +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_RTC_UC from ryu.services.protocols.bgp.utils.circlist import CircularListType from ryu.services.protocols.bgp.utils.evtlet import LoopingCall @@ -42,10 +46,10 @@ OrderedDict = OrderedDict # Currently supported address families. -SUPPORTED_GLOBAL_RF = set([nlri.RF_IPv4_UC, - nlri.RF_IPv4_VPN, - nlri.RF_RTC_UC, - nlri.RF_IPv6_VPN +SUPPORTED_GLOBAL_RF = set([RF_IPv4_UC, + RF_IPv4_VPN, + RF_RTC_UC, + RF_IPv6_VPN ]) diff --git a/ryu/services/protocols/bgp/core.py b/ryu/services/protocols/bgp/core.py index 42bbe151..f38ece13 100644 --- a/ryu/services/protocols/bgp/core.py +++ b/ryu/services/protocols/bgp/core.py @@ -21,9 +21,12 @@ """ import logging -from ryu.services.protocols.bgp.protocols.bgp import exceptions -from ryu.services.protocols.bgp.protocols.bgp import nlri -from ryu.services.protocols.bgp.protocols.bgp import pathattr +from ryu.lib.packet.bgp import BGP_ERROR_CEASE +from ryu.lib.packet.bgp import BGP_ERROR_SUB_CONNECTION_RESET +from ryu.lib.packet.bgp import BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION +from ryu.lib.packet.bgp import RF_RTC_UC +from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE + from ryu.services.protocols.bgp.base import Activity from ryu.services.protocols.bgp.base import add_bgp_error_metadata from ryu.services.protocols.bgp.base import BGPSException @@ -45,7 +48,7 @@ LOG = logging.getLogger('bgpspeaker.core') CORE_IP = '0.0.0.0' # Required dictates that Origin attribute be incomplete -EXPECTED_ORIGIN = pathattr.Origin.INCOMPLETE +EXPECTED_ORIGIN = BGP_ATTR_ORIGIN_INCOMPLETE @add_bgp_error_metadata(code=CORE_ERROR_CODE, sub_code=1, @@ -222,9 +225,9 @@ class CoreService(Factory, Activity): server_thread.wait() processor_thread.wait() - #========================================================================= + # ======================================================================== # RTC address family related utilities - #========================================================================= + # ======================================================================== def update_rtfilters(self): """Updates RT filters for each peer. @@ -271,7 +274,7 @@ class CoreService(Factory, Activity): - `old_rts`: (set) of RTs that peers is no longer interested in. """ for table in self._table_manager._global_tables.itervalues(): - if table.route_family == nlri.RF_RTC_UC: + if table.route_family == RF_RTC_UC: continue self._spawn('rt_filter_chg_%s' % peer, self._rt_mgr.on_rt_filter_chg_sync_peer, @@ -340,9 +343,9 @@ class CoreService(Factory, Activity): return rtfilter_map - #========================================================================= + # ======================================================================== # Peer or Neighbor related handles/utilities. - #========================================================================= + # ======================================================================== def register_flexinet_sink(self, sink): self._sinks.add(sink) @@ -408,8 +411,8 @@ class CoreService(Factory, Activity): LOG.debug('Closed connection to %s:%s as it is not a recognized' ' peer.' % (peer_addr, peer_port)) # Send connection rejected notification as per RFC - code = exceptions.ConnRejected.CODE - subcode = exceptions.ConnRejected.SUB_CODE + code = BGP_ERROR_CEASE + subcode = BGP_ERROR_SUB_CONNECTION_RESET bgp_proto.send_notification(code, subcode) elif not (peer.in_idle() or peer.in_active() or peer.in_connect()): LOG.debug('Closing connection to %s:%s as we have connection' @@ -417,8 +420,8 @@ class CoreService(Factory, Activity): ' i.e. connection resolution' % (peer_addr, peer_port)) # Send Connection Collision Resolution notification as per RFC. - code = exceptions.CollisionResolution.CODE - subcode = exceptions.CollisionResolution.SUB_CODE + code = BGP_ERROR_CEASE + subcode = BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION bgp_proto.send_notification(code, subcode) else: self._spawn_activity(bgp_proto, peer) diff --git a/ryu/services/protocols/bgp/core_managers/peer_manager.py b/ryu/services/protocols/bgp/core_managers/peer_manager.py index 1b923862..505ffc8d 100644 --- a/ryu/services/protocols/bgp/core_managers/peer_manager.py +++ b/ryu/services/protocols/bgp/core_managers/peer_manager.py @@ -3,11 +3,15 @@ import logging from ryu.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF from ryu.services.protocols.bgp.model import OutgoingRoute from ryu.services.protocols.bgp.peer import Peer -from ryu.services.protocols.bgp.protocols.bgp import pathattr -from ryu.services.protocols.bgp.protocols.bgp import nlri +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_COMMUNITIES +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_RTC_UC from ryu.services.protocols.bgp.utils.bgp \ import clone_path_and_update_med_for_target_neighbor - LOG = logging.getLogger('bgpspeaker.core_managers.peer_manager') @@ -64,7 +68,7 @@ class PeerManager(object): non_rtc_peer_list = set() for peer in self._peers.itervalues(): if (peer.in_established() and - not peer.is_mpbgp_cap_valid(nlri.RF_RTC_UC)): + not peer.is_mpbgp_cap_valid(RF_RTC_UC)): non_rtc_peer_list.add(peer) return non_rtc_peer_list @@ -115,8 +119,8 @@ class PeerManager(object): # wasn't set at all now it could have changed and we may # need to set new value there p = sent_route.path - if p.med_set_by_target_neighbor\ - or p.get_pattr(pathattr.Med.ATTR_NAME) is None: + if p.med_set_by_target_neighbor or p.get_pattr( + BGP_ATTR_TYPE_MULTI_EXIT_DISC) is None: sent_route.path = \ clone_path_and_update_med_for_target_neighbor( sent_route.path, peer.med @@ -131,7 +135,7 @@ class PeerManager(object): Skips making request to peer that have valid RTC capability. """ - assert route_family != nlri.RF_RTC_UC + assert route_family != RF_RTC_UC for peer in self._peers.itervalues(): # First check if peer is in established state if (peer.in_established and @@ -139,7 +143,7 @@ class PeerManager(object): # family peer.is_mbgp_cap_valid(route_family) and # Check if peer has valid capability for RTC - not peer.is_mbgp_cap_valid(nlri.RF_RTC_UC)): + not peer.is_mbgp_cap_valid(RF_RTC_UC)): peer.request_route_refresh(route_family) def make_route_refresh_request(self, peer_ip, *route_families): @@ -185,7 +189,7 @@ class PeerManager(object): match this setting. """ # First check if for this peer mpbgp-rtc is valid. - if not peer.is_mbgp_cap_valid(nlri.RF_RTC_UC): + if not peer.is_mbgp_cap_valid(RF_RTC_UC): return neigh_conf = self._neighbors_conf.get_neighbor_conf(peer.ip_address) @@ -209,7 +213,7 @@ class PeerManager(object): peer.communicate_path(best_path) # Also communicate EOR as per RFC - peer.enque_end_of_rib(nlri.RF_RTC_UC) + peer.enque_end_of_rib(RF_RTC_UC) def comm_all_best_paths(self, peer): """Shares/communicates current best paths with this peers. @@ -221,7 +225,7 @@ class PeerManager(object): ' 1/132') # We will enqueue best path from all global destination. for route_family, table in self._table_manager.iter: - if route_family == nlri.RF_RTC_UC: + if route_family == RF_RTC_UC: continue if peer.is_mbgp_cap_valid(route_family): for dest in table.itervalues(): @@ -240,10 +244,10 @@ class PeerManager(object): # Filter based on standard community # If new best path has community attribute, it should be taken into # account when sending UPDATE to peers. - comm_attr = new_best_path.get_pattr(pathattr.Community.ATTR_NAME) + comm_attr = new_best_path.get_pattr(BGP_ATTR_TYPE_COMMUNITIES) if comm_attr: comm_attr_na = comm_attr.has_comm_attr( - pathattr.Community.NO_ADVERTISE + BGPPathAttributeCommunities.NO_ADVERTISE ) # If we have NO_ADVERTISE attribute is present, we do not send # UPDATE to any peers @@ -277,7 +281,7 @@ class PeerManager(object): if path_rts: # We add Default_RTC_NLRI to path RTs so that we can send it to # peers that have expressed interest in all paths - path_rts.append(nlri.RtNlri.DEFAULT_RT) + path_rts.append(RouteTargetMembershipNLRI.DEFAULT_RT) # All peers that do not have RTC capability qualify qualified_peers = set(self._get_non_rtc_peers()) # Peers that have RTC capability and have common RT with the path @@ -299,7 +303,7 @@ class PeerManager(object): for route_family in SUPPORTED_GLOBAL_RF: # Since we are dealing with peers that do not support RTC, # ignore this address family - if route_family == nlri.RF_RTC_UC: + if route_family == RF_RTC_UC: continue self.req_rr_to_non_rtc_peers(route_family) diff --git a/ryu/services/protocols/bgp/core_managers/table_manager.py b/ryu/services/protocols/bgp/core_managers/table_manager.py index 640b6108..a701644f 100644 --- a/ryu/services/protocols/bgp/core_managers/table_manager.py +++ b/ryu/services/protocols/bgp/core_managers/table_manager.py @@ -14,8 +14,21 @@ from ryu.services.protocols.bgp.info_base.vrf6 import Vrf6Table from ryu.services.protocols.bgp.rtconf import vrfs from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV4 from ryu.services.protocols.bgp.rtconf.vrfs import VRF_RF_IPV6 -from ryu.services.protocols.bgp.protocols.bgp import pathattr -from ryu.services.protocols.bgp.protocols.bgp import nlri + +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_RTC_UC +from ryu.lib.packet.bgp import BGPPathAttributeNextHop +from ryu.lib.packet.bgp import BGPPathAttributeOrigin +from ryu.lib.packet.bgp import BGPPathAttributeAsPath +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH +from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP +from ryu.lib.packet.bgp import IPAddrPrefix +from ryu.lib.packet.bgp import IP6AddrPrefix + from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4 from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4_prefix from ryu.services.protocols.bgp.utils.validation import is_valid_ipv6 @@ -150,16 +163,16 @@ class TableCoreManager(object): ) global_table = None - if route_family == nlri.RF_IPv4_UC: + if route_family == RF_IPv4_UC: global_table = self.get_ipv4_table() - elif route_family == nlri.RF_IPv4_VPN: + elif route_family == RF_IPv4_VPN: global_table = self.get_vpn4_table() - elif route_family == nlri.RF_IPv6_VPN: + elif route_family == RF_IPv6_VPN: global_table = self.get_vpn6_table() - elif route_family == nlri.RF_RTC_UC: + elif route_family == RF_RTC_UC: global_table = self.get_rtc_table() return global_table @@ -184,12 +197,12 @@ class TableCoreManager(object): Creates the table if it does not exist. """ - vpn_table = self._global_tables.get(nlri.RF_IPv4_UC) + vpn_table = self._global_tables.get(RF_IPv4_UC) # Lazy initialize the table. if not vpn_table: vpn_table = Ipv4Table(self._core_service, self._signal_bus) - self._global_tables[nlri.RF_IPv4_UC] = vpn_table - self._tables[(None, nlri.RF_IPv4_UC)] = vpn_table + self._global_tables[RF_IPv4_UC] = vpn_table + self._tables[(None, RF_IPv4_UC)] = vpn_table return vpn_table @@ -198,12 +211,12 @@ class TableCoreManager(object): Creates the table if it does not exist. """ - vpn_table = self._global_tables.get(nlri.RF_IPv6_VPN) + vpn_table = self._global_tables.get(RF_IPv6_VPN) # Lazy initialize the table. if not vpn_table: vpn_table = Vpnv6Table(self._core_service, self._signal_bus) - self._global_tables[nlri.RF_IPv6_VPN] = vpn_table - self._tables[(None, nlri.RF_IPv6_VPN)] = vpn_table + self._global_tables[RF_IPv6_VPN] = vpn_table + self._tables[(None, RF_IPv6_VPN)] = vpn_table return vpn_table @@ -212,12 +225,12 @@ class TableCoreManager(object): Creates the table if it does not exist. """ - vpn_table = self._global_tables.get(nlri.RF_IPv4_VPN) + vpn_table = self._global_tables.get(RF_IPv4_VPN) # Lazy initialize the table. if not vpn_table: vpn_table = Vpnv4Table(self._core_service, self._signal_bus) - self._global_tables[nlri.RF_IPv4_VPN] = vpn_table - self._tables[(None, nlri.RF_IPv4_VPN)] = vpn_table + self._global_tables[RF_IPv4_VPN] = vpn_table + self._tables[(None, RF_IPv4_VPN)] = vpn_table return vpn_table @@ -226,12 +239,12 @@ class TableCoreManager(object): Creates the table if it does not exist. """ - rtc_table = self._global_tables.get(nlri.RF_RTC_UC) + rtc_table = self._global_tables.get(RF_RTC_UC) # Lazy initialization of the table. if not rtc_table: rtc_table = RtcTable(self._core_service, self._signal_bus) - self._global_tables[nlri.RF_RTC_UC] = rtc_table - self._tables[(None, nlri.RF_RTC_UC)] = rtc_table + self._global_tables[RF_RTC_UC] = rtc_table + self._tables[(None, RF_RTC_UC)] = rtc_table return rtc_table def get_next_vpnv4_label(self): @@ -379,7 +392,7 @@ class TableCoreManager(object): for route_family in SUPPORTED_GLOBAL_RF: # TODO(PH): We currently do not install RT_NLRI paths based on # extended path attributes (RT) - if route_family == nlri.RF_RTC_UC: + if route_family == RF_RTC_UC: continue table = self.get_global_table_by_route_family(route_family) uninteresting_dest_count += \ @@ -407,9 +420,9 @@ class TableCoreManager(object): interested_tables = set() # Get route family of VRF to when this VPN Path can be imported to - route_family = nlri.RF_IPv4_UC - if vpn_path.route_family != nlri.RF_IPv4_VPN: - route_family = nlri.RF_IPv6_UC + route_family = RF_IPv4_UC + if vpn_path.route_family != RF_IPv4_VPN: + route_family = RF_IPv6_UC for rt in path_rts: rt_rf_id = rt + ':' + str(route_family) vrf_rt_tables = self._tables_for_rt.get(rt_rf_id) @@ -454,7 +467,8 @@ class TableCoreManager(object): 'exist.' % route_dist) if not is_valid_ipv4_prefix(prefix) or not is_valid_ipv4(next_hop): raise BgpCoreError(desc='Invalid Ipv4 prefix or nexthop.') - prefix = nlri.Ipv4(prefix) + ip, masklen = prefix.split('/') + prefix = IPAddrPrefix(int(masklen), ip) elif route_family == VRF_RF_IPV6: vrf_table = self._tables.get(table_id) if vrf_table is None: @@ -462,24 +476,26 @@ class TableCoreManager(object): 'exist.' % route_dist) if not is_valid_ipv6_prefix(prefix) or not is_valid_ipv6(next_hop): raise BgpCoreError(desc='Invalid Ipv6 prefix or nexthop.') - prefix = nlri.Ipv6(prefix) + ip6, masklen = prefix.split('/') + prefix = IP6AddrPrefix(int(masklen), ip6) return vrf_table.insert_vrf_path( prefix, next_hop=next_hop, gen_lbl=True ) def add_to_ipv4_global_table(self, prefix): - _nlri = nlri.Ipv4(prefix) + ip, masklen = prefix.split('/') + _nlri = IPAddrPrefix(int(masklen), ip) src_ver_num = 1 peer = None # set mandatory path attributes - nexthop = pathattr.NextHop("0.0.0.0") - origin = pathattr.Origin('igp') - aspath = pathattr.AsPath([[]]) + nexthop = BGPPathAttributeNextHop("0.0.0.0") + origin = BGPPathAttributeOrigin(BGP_ATTR_ORIGIN_IGP) + aspath = BGPPathAttributeAsPath([[]]) pathattrs = OrderedDict() - pathattrs[origin.ATTR_NAME] = origin - pathattrs[aspath.ATTR_NAME] = aspath + pathattrs[BGP_ATTR_TYPE_ORIGIN] = origin + pathattrs[BGP_ATTR_TYPE_AS_PATH] = aspath new_path = Ipv4Path(peer, _nlri, src_ver_num, pattrs=pathattrs, nexthop=nexthop) @@ -510,13 +526,15 @@ class TableCoreManager(object): if not vrf_table: raise BgpCoreError(desc='Vrf for route distinguisher %s does ' 'not exist.' % route_dist) - prefix = nlri.Ipv4(prefix) + ip, masklen = prefix.split('/') + prefix = IPAddrPrefix(int(masklen), ip) else: vrf_table = self._tables.get(table_id) if not vrf_table: raise BgpCoreError(desc='Vrf for route distinguisher %s does ' 'not exist.' % route_dist) - prefix = nlri.Ipv6(prefix) + ip6, masklen = prefix.split('/') + prefix = IP6AddrPrefix(int(masklen), ip) # We do not check if we have a path to given prefix, we issue # withdrawal. Hence multiple withdrawals have not side effect. return vrf_table.insert_vrf_path(prefix, is_withdraw=True) diff --git a/ryu/services/protocols/bgp/info_base/base.py b/ryu/services/protocols/bgp/info_base/base.py index 408be52e..c735c309 100644 --- a/ryu/services/protocols/bgp/info_base/base.py +++ b/ryu/services/protocols/bgp/info_base/base.py @@ -24,9 +24,9 @@ from abc import abstractmethod from copy import copy import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RtNlri -from ryu.services.protocols.bgp.protocols.bgp.pathattr import ExtCommunity +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RouteTargetMembershipNLRI +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES from ryu.services.protocols.bgp.base import OrderedDict from ryu.services.protocols.bgp.constants import VPN_TABLE @@ -169,7 +169,7 @@ class Table(object): def _validate_nlri(self, nlri): """Validated *nlri* is the type that this table stores/supports. """ - if not nlri or not (nlri.route_family == self.route_family): + if not nlri or not (nlri.ROUTE_FAMILY == self.route_family): raise ValueError('Invalid Vpnv4 prefix given.') def _validate_path(self, path): @@ -661,10 +661,10 @@ class Path(object): - `is_withdraw`: (bool) True if this represents a withdrawal. """ self.med_set_by_target_neighbor = med_set_by_target_neighbor - if nlri.route_family != self.__class__.ROUTE_FAMILY: + if nlri.ROUTE_FAMILY != self.__class__.ROUTE_FAMILY: raise ValueError('NLRI and Path route families do not' ' match (%s, %s).' % - (nlri.route_family, self.__class__.ROUTE_FAMILY)) + (nlri.ROUTE_FAMILY, self.__class__.ROUTE_FAMILY)) # Currently paths injected directly into VRF has only one source # src_peer can be None to denote NC else has to be instance of Peer. @@ -760,7 +760,8 @@ class Path(object): return clone def get_rts(self): - extcomm_attr = self._path_attr_map.get(ExtCommunity.ATTR_NAME) + extcomm_attr = self._path_attr_map.get( + BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) if extcomm_attr is None: rts = [] else: @@ -775,7 +776,7 @@ class Path(object): curr_rts = self.get_rts() # Add default RT to path RTs so that we match interest for peers who # advertised default RT - curr_rts.append(RtNlri.DEFAULT_RT) + curr_rts.append(RouteTargetMembershipNLRI.DEFAULT_RT) return not interested_rts.isdisjoint(curr_rts) diff --git a/ryu/services/protocols/bgp/info_base/ipv4.py b/ryu/services/protocols/bgp/info_base/ipv4.py index e7bdd8ff..f61bf7c7 100644 --- a/ryu/services/protocols/bgp/info_base/ipv4.py +++ b/ryu/services/protocols/bgp/info_base/ipv4.py @@ -7,8 +7,8 @@ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import Ipv4 -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_UC +from ryu.lib.packet.bgp import IPAddrPrefix +from ryu.lib.packet.bgp import RF_IPv4_UC from ryu.services.protocols.bgp.info_base.base import Path from ryu.services.protocols.bgp.info_base.base import Table @@ -63,7 +63,7 @@ class Ipv4Path(Path): """Represents a way of reaching an VPNv4 destination.""" ROUTE_FAMILY = RF_IPv4_UC VRF_PATH_CLASS = None # defined in init - anti cyclic import hack - NLRI_CLASS = Ipv4 + NLRI_CLASS = IPAddrPrefix def __init__(self, *args, **kwargs): super(Ipv4Path, self).__init__(*args, **kwargs) diff --git a/ryu/services/protocols/bgp/info_base/rtc.py b/ryu/services/protocols/bgp/info_base/rtc.py index fd65b13e..6f6e3321 100644 --- a/ryu/services/protocols/bgp/info_base/rtc.py +++ b/ryu/services/protocols/bgp/info_base/rtc.py @@ -19,7 +19,7 @@ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_RTC_UC +from ryu.lib.packet.bgp import RF_RTC_UC from ryu.services.protocols.bgp.info_base.base import Destination from ryu.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin diff --git a/ryu/services/protocols/bgp/info_base/vpnv4.py b/ryu/services/protocols/bgp/info_base/vpnv4.py index 06bac841..26eeb966 100644 --- a/ryu/services/protocols/bgp/info_base/vpnv4.py +++ b/ryu/services/protocols/bgp/info_base/vpnv4.py @@ -19,8 +19,8 @@ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import Ipv4 -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_VPN +from ryu.lib.packet.bgp import IPAddrPrefix +from ryu.lib.packet.bgp import RF_IPv4_VPN from ryu.services.protocols.bgp.info_base.vpn import VpnDest from ryu.services.protocols.bgp.info_base.vpn import VpnPath @@ -51,7 +51,7 @@ class Vpnv4Path(VpnPath): """Represents a way of reaching an VPNv4 destination.""" ROUTE_FAMILY = RF_IPv4_VPN VRF_PATH_CLASS = None # defined in init - anti cyclic import hack - NLRI_CLASS = Ipv4 + NLRI_CLASS = IPAddrPrefix def __init__(self, *args, **kwargs): super(Vpnv4Path, self).__init__(*args, **kwargs) diff --git a/ryu/services/protocols/bgp/info_base/vpnv6.py b/ryu/services/protocols/bgp/info_base/vpnv6.py index 69950e78..d66e2736 100644 --- a/ryu/services/protocols/bgp/info_base/vpnv6.py +++ b/ryu/services/protocols/bgp/info_base/vpnv6.py @@ -19,8 +19,8 @@ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import Ipv6 -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_VPN +from ryu.lib.packet.bgp import IP6AddrPrefix +from ryu.lib.packet.bgp import RF_IPv6_VPN from ryu.services.protocols.bgp.info_base.vpn import VpnDest from ryu.services.protocols.bgp.info_base.vpn import VpnPath @@ -51,7 +51,7 @@ class Vpnv6Path(VpnPath): """Represents a way of reaching an VPNv4 destination.""" ROUTE_FAMILY = RF_IPv6_VPN VRF_PATH_CLASS = None # defined in init - anti cyclic import hack - NLRI_CLASS = Ipv6 + NLRI_CLASS = IP6AddrPrefix def __init__(self, *args, **kwargs): super(Vpnv6Path, self).__init__(*args, **kwargs) diff --git a/ryu/services/protocols/bgp/info_base/vrf.py b/ryu/services/protocols/bgp/info_base/vrf.py index b2618a9d..30b53a27 100644 --- a/ryu/services/protocols/bgp/info_base/vrf.py +++ b/ryu/services/protocols/bgp/info_base/vrf.py @@ -20,6 +20,15 @@ import abc import logging +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC +from ryu.lib.packet.bgp import BGPPathAttributeOrigin +from ryu.lib.packet.bgp import BGPPathAttributeAsPath +from ryu.lib.packet.bgp import BGPPathAttributeExtendedCommunities +from ryu.lib.packet.bgp import BGPPathAttributeMultiExitDisc + from ryu.services.protocols.bgp.base import OrderedDict from ryu.services.protocols.bgp.constants import VPN_TABLE from ryu.services.protocols.bgp.constants import VRF_TABLE @@ -30,7 +39,6 @@ from ryu.services.protocols.bgp.utils.stats import LOCAL_ROUTES from ryu.services.protocols.bgp.utils.stats import REMOTE_ROUTES from ryu.services.protocols.bgp.utils.stats import RESOURCE_ID from ryu.services.protocols.bgp.utils.stats import RESOURCE_NAME -from ryu.services.protocols.bgp.protocols.bgp import pathattr LOG = logging.getLogger('bgpspeaker.info_base.vrf') @@ -201,15 +209,15 @@ class VrfTable(Table): # in the path. Hence we do not add these attributes here. from ryu.services.protocols.bgp.core import EXPECTED_ORIGIN - pattrs[pathattr.Origin.ATTR_NAME] = \ - pathattr.Origin(EXPECTED_ORIGIN) - pattrs[pathattr.AsPath.ATTR_NAME] = pathattr.AsPath([]) - pattrs[pathattr.ExtCommunity.ATTR_NAME] = pathattr.ExtCommunity( + pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( + EXPECTED_ORIGIN) + pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) + pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = \ + BGPPathAttributeExtendedCommunities( rt_list=vrf_conf.export_rts, soo_list=vrf_conf.soo_list) if vrf_conf.multi_exit_disc: - pattrs[pathattr.Med.ATTR_NAME] = pathattr.Med( - vrf_conf.multi_exit_disc - ) + pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = \ + BGPPathAttributeMultiExitDisc(vrf_conf.multi_exit_disc) table_manager = self._core_service.table_manager if gen_lbl and next_hop: @@ -526,5 +534,5 @@ class VrfRtImportMap(ImportMap): self._rt = rt def match(self, vrf_path): - extcomm = vrf_path.pathattr_map.get('extcommunity') + extcomm = vrf_path.pathattr_map.get(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) return extcomm is not None and self._rt in extcomm.rt_list diff --git a/ryu/services/protocols/bgp/info_base/vrf4.py b/ryu/services/protocols/bgp/info_base/vrf4.py index 4e2d7f2f..1a00b39d 100644 --- a/ryu/services/protocols/bgp/info_base/vrf4.py +++ b/ryu/services/protocols/bgp/info_base/vrf4.py @@ -21,10 +21,10 @@ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import Ipv4 -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_VPN -from ryu.services.protocols.bgp.protocols.bgp.nlri import Vpnv4 +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import IPAddrPrefix +from ryu.lib.packet.bgp import LabelledVPNIPAddrPrefix from ryu.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path from ryu.services.protocols.bgp.info_base.vrf import VrfDest @@ -39,7 +39,7 @@ class Vrf4Path(VrfPath): """Represents a way of reaching an IP destination with a VPN.""" ROUTE_FAMILY = RF_IPv4_UC VPN_PATH_CLASS = Vpnv4Path - VPN_NLRI_CLASS = Vpnv4 + VPN_NLRI_CLASS = LabelledVPNIPAddrPrefix class Vrf4Dest(VrfDest): @@ -50,11 +50,11 @@ class Vrf4Table(VrfTable): """Virtual Routing and Forwarding information base for IPv4.""" ROUTE_FAMILY = RF_IPv4_UC VPN_ROUTE_FAMILY = RF_IPv4_VPN - NLRI_CLASS = Ipv4 + NLRI_CLASS = IPAddrPrefix VRF_PATH_CLASS = Vrf4Path VRF_DEST_CLASS = Vrf4Dest class Vrf4NlriImportMap(VrfNlriImportMap): VRF_PATH_CLASS = Vrf4Path - NLRI_CLASS = Ipv4 + NLRI_CLASS = IPAddrPrefix diff --git a/ryu/services/protocols/bgp/info_base/vrf6.py b/ryu/services/protocols/bgp/info_base/vrf6.py index c011d79f..f2939324 100644 --- a/ryu/services/protocols/bgp/info_base/vrf6.py +++ b/ryu/services/protocols/bgp/info_base/vrf6.py @@ -21,10 +21,10 @@ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import Ipv6 -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_VPN -from ryu.services.protocols.bgp.protocols.bgp.nlri import Vpnv6 +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import IP6AddrPrefix +from ryu.lib.packet.bgp import LabelledVPNIP6AddrPrefix from ryu.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path from ryu.services.protocols.bgp.info_base.vrf import VrfDest @@ -39,7 +39,7 @@ class Vrf6Path(VrfPath): """Represents a way of reaching an IP destination with a VPN.""" ROUTE_FAMILY = RF_IPv6_UC VPN_PATH_CLASS = Vpnv6Path - VPN_NLRI_CLASS = Vpnv6 + VPN_NLRI_CLASS = LabelledVPNIP6AddrPrefix class Vrf6Dest(VrfDest): @@ -51,11 +51,11 @@ class Vrf6Table(VrfTable): """Virtual Routing and Forwarding information base for IPv6.""" ROUTE_FAMILY = RF_IPv6_UC VPN_ROUTE_FAMILY = RF_IPv6_VPN - NLRI_CLASS = Ipv6 + NLRI_CLASS = IP6AddrPrefix VRF_PATH_CLASS = Vrf6Path VRF_DEST_CLASS = Vrf6Dest class Vrf6NlriImportMap(VrfNlriImportMap): VRF_PATH_CLASS = Vrf6Path - NLRI_CLASS = Ipv6 + NLRI_CLASS = IP6AddrPrefix diff --git a/ryu/services/protocols/bgp/operator/commands/show/neighbor.py b/ryu/services/protocols/bgp/operator/commands/show/neighbor.py index 2e8b8715..bd3fda7c 100644 --- a/ryu/services/protocols/bgp/operator/commands/show/neighbor.py +++ b/ryu/services/protocols/bgp/operator/commands/show/neighbor.py @@ -8,10 +8,10 @@ from ryu.services.protocols.bgp.operator.command import STATUS_OK from ryu.services.protocols.bgp.operator.commands.responses import \ WrongParamResp from ryu.services.protocols.bgp.operator.views.bgp import CoreServiceDetailView -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_VPN -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN LOG = logging.getLogger('bgpspeaker.operator.commands.show.summary') diff --git a/ryu/services/protocols/bgp/operator/internal_api.py b/ryu/services/protocols/bgp/operator/internal_api.py index ab7255a1..b83ce0d3 100644 --- a/ryu/services/protocols/bgp/operator/internal_api.py +++ b/ryu/services/protocols/bgp/operator/internal_api.py @@ -1,9 +1,13 @@ import logging import traceback -from ryu.services.protocols.bgp.protocols.bgp import nlri -from ryu.services.protocols.bgp.protocols.bgp.pathattr import AsPath -from ryu.services.protocols.bgp.protocols.bgp.pathattr import Med +from ryu.lib.packet.bgp import RouteFamily +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_RTC_UC + from ryu.services.protocols.bgp.base import add_bgp_error_metadata from ryu.services.protocols.bgp.base import BGPSException from ryu.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF @@ -67,10 +71,11 @@ class InternalApi(object): def get_single_rib_routes(self, addr_family): rfs = { - 'ipv4': nlri.get_rf(1, 1), - 'vpnv4': nlri.get_rf(1, 128), - 'vpnv6': nlri.get_rf(2, 128), - 'rtfilter': nlri.get_rf(1, 132) + 'ipv4': RF_IPv4_UC, + 'ipv6': RF_IPv6_UC, + 'vpnv4': RF_IPv4_VPN, + 'vpnv6': RF_IPv6_VPN, + 'rtfilter': RF_RTC_UC } if addr_family not in rfs: raise WrongParamError('Unknown or unsupported family') @@ -89,13 +94,13 @@ class InternalApi(object): 'prefix': dst.nlri.formatted_nlri_str} def _path_to_dict(dst, path): - aspath = path.get_pattr(AsPath.ATTR_NAME).path_seg_list + aspath = path.get_pattr(BGP_ATTR_TYPE_AS_PATH).path_seg_list if aspath is None or len(aspath) == 0: aspath = '' nexthop = path.nexthop # Get the MED path attribute - med = path.get_pattr(Med.ATTR_NAME) + med = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC) med = med.value if med else '' # Get best path reason bpr = dst.best_path_reason if path == dst.best_path else '' @@ -134,7 +139,7 @@ class InternalApi(object): if afi is None and safi is None: route_families.extend(SUPPORTED_GLOBAL_RF) else: - route_family = nlri.get_rf(afi, safi) + route_family = RouteFamily(afi, safi) if (route_family not in SUPPORTED_GLOBAL_RF): raise WrongParamError('Not supported address-family' ' %s, %s' % (afi, safi)) diff --git a/ryu/services/protocols/bgp/operator/views/bgp.py b/ryu/services/protocols/bgp/operator/views/bgp.py index 6f53d4f4..f78f2a9f 100644 --- a/ryu/services/protocols/bgp/operator/views/bgp.py +++ b/ryu/services/protocols/bgp/operator/views/bgp.py @@ -5,8 +5,11 @@ from ryu.services.protocols.bgp.operator.views.base import \ from ryu.services.protocols.bgp.operator.views.base import OperatorDetailView from ryu.services.protocols.bgp.operator.views import fields -from ryu.services.protocols.bgp.protocols.bgp import pathattr - +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES class CoreServiceDetailView(OperatorDetailView): rf_state = fields.RelatedViewField( @@ -144,18 +147,19 @@ class PathDetailView(OperatorDetailView): ret = super(PathDetailView, self).encode() ret['nlri'] = self.rel('nlri').encode() ret['route_family'] = self.rel('route_family').encode() - as_path = self.get_field('pathattr_map').get(pathattr.AsPath.ATTR_NAME) - origin = self.get_field('pathattr_map').get(pathattr.Origin.ATTR_NAME) - metric = self.get_field('pathattr_map').get(pathattr.Med.ATTR_NAME) + as_path = self.get_field('pathattr_map').get(BGP_ATTR_TYPE_AS_PATH) + origin = self.get_field('pathattr_map').get(BGP_ATTR_TYPE_ORIGIN) + metric = self.get_field('pathattr_map').get( + BGP_ATTR_TYPE_MULTI_EXIT_DISC) local_pref = self.get_field('pathattr_map').get( - pathattr.LocalPref.ATTR_NAME + BGP_ATTR_TYPE_LOCAL_PREF ) ret['as_path'] = as_path.value if as_path else None ret['origin'] = origin.value if origin else None ret['metric'] = metric.value if metric else None ret['local_pref'] = local_pref.value if local_pref else None - ext = ret['pathattr_map'].get(pathattr.ExtCommunity.ATTR_NAME) + ext = ret['pathattr_map'].get(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) del ret['pathattr_map'] if ext: ret['rt_list'] = ext.rt_list @@ -215,11 +219,13 @@ class VpnNlriDetailView(IpNlriDetailView): class NlriDetailView(OperatorDetailView): def __new__(cls, obj, filter_func=None): - from ryu.services.protocols.bgp.protocols.bgp.nlri import Vpnv4, Vpnv6 - from ryu.services.protocols.bgp.protocols.bgp.nlri import Ipv4, Ipv6 - if isinstance(obj, (Vpnv4, Vpnv6)): + from ryu.lib.packet.bgp import LabelledVPNIPAddrPrefix + from ryu.lib.packet.bgp import LabelledVPNIP6AddrPrefix + from ryu.lib.packet.bgp import IPAddrPrefix, IP6AddrPrefix + if isinstance(obj, (LabelledVPNIPAddrPrefix, + LabelledVPNIP6AddrPrefix)): return VpnNlriDetailView(obj) - elif isinstance(obj, (Ipv4, Ipv6)): + elif isinstance(obj, (IPAddrPrefix, IP6AddrPrefix)): return IpNlriDetailView(obj) else: return OperatorDetailView(obj, filter_func) diff --git a/ryu/services/protocols/bgp/peer.py b/ryu/services/protocols/bgp/peer.py index f2e78a6a..4bca6165 100644 --- a/ryu/services/protocols/bgp/peer.py +++ b/ryu/services/protocols/bgp/peer.py @@ -36,11 +36,39 @@ from ryu.services.protocols.bgp.speaker import BgpProtocol from ryu.services.protocols.bgp.utils import bgp as bgp_utils from ryu.services.protocols.bgp.utils.evtlet import EventletIOFactory from ryu.services.protocols.bgp.utils import stats -from ryu.services.protocols.bgp.protocols.bgp import exceptions -from ryu.services.protocols.bgp.protocols.bgp import messages -from ryu.services.protocols.bgp.protocols.bgp import nlri -from ryu.services.protocols.bgp.protocols.bgp import pathattr +from ryu.lib.packet import bgp + +from ryu.lib.packet.bgp import RouteFamily +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_RTC_UC + +from ryu.lib.packet.bgp import BGPOpen +from ryu.lib.packet.bgp import BGPUpdate +from ryu.lib.packet.bgp import BGPRouteRefresh + +from ryu.lib.packet.bgp import BGP_MSG_UPDATE +from ryu.lib.packet.bgp import BGP_MSG_KEEPALIVE +from ryu.lib.packet.bgp import BGP_MSG_ROUTE_REFRESH + +from ryu.lib.packet.bgp import BGPPathAttributeNextHop +from ryu.lib.packet.bgp import BGPPathAttributeAsPath +from ryu.lib.packet.bgp import BGPPathAttributeLocalPref +from ryu.lib.packet.bgp import BGPPathAttributeExtendedCommunities +from ryu.lib.packet.bgp import BGPPathAttributeMpReachNLRI +from ryu.lib.packet.bgp import BGPPathAttributeMpUnreachNLRI + +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_NEXT_HOP +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MP_REACH_NLRI +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MP_UNREACH_NLRI +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_COMMUNITIES +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_EXTENDED_COMMUNITIES LOG = logging.getLogger('bgpspeaker.peer') @@ -110,7 +138,7 @@ class PeerState(object): } self._signal_bus = signal_bus - #TODO(JK): refactor other counters to use signals also + # TODO(JK): refactor other counters to use signals also self._signal_bus.register_listener( ('error', 'bgp', self.peer), self._remember_last_bgp_error @@ -264,12 +292,12 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # State per route family, {RouteFamily: PeerRf,}. self.rf_state = {} # Get vpnv4 route family settings. - prf = PeerRf(self, nlri.RF_IPv4_VPN, + prf = PeerRf(self, RF_IPv4_VPN, enabled=self._neigh_conf.cap_mbgp_vpnv4) - self.rf_state[nlri.RF_IPv4_VPN] = prf + self.rf_state[RF_IPv4_VPN] = prf # Get vpnv6 route family settings. - prf = PeerRf(self, nlri.RF_IPv6_VPN, self._neigh_conf.cap_mbgp_vpnv6) - self.rf_state[nlri.RF_IPv6_VPN] = prf + prf = PeerRf(self, RF_IPv6_VPN, self._neigh_conf.cap_mbgp_vpnv6) + self.rf_state[RF_IPv6_VPN] = prf # Bound protocol instance self._protocol = None @@ -378,8 +406,8 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # when we stop the protocol, hence we call connection_lost # here as we triggered socket to close. self._protocol.send_notification( - exceptions.AdminShutdown.CODE, - exceptions.AdminShutdown.SUB_CODE + BGP_ERROR_CEASE, + BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN ) self._protocol.stop() # If this peer is not enabled any-more we stop trying to make any @@ -415,7 +443,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): Update appropriate counters and set appropriate timers. """ - assert rr_msg.TYPE_CODE == messages.RouteRefresh.TYPE_CODE + assert rr_msg.TYPE_CODE == BGP_MSG_ROUTE_REFRESH self._protocol.send(rr_msg) LOG.debug('RouteRefresh %s>> %s' % (self._neigh_conf.ip_address, rr_msg)) @@ -471,18 +499,18 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # Check currently supported out-going msgs. assert isinstance( outgoing_msg, - (messages.RouteRefresh, messages.Update, OutgoingRoute) + (BGPRouteRefresh, BGPUpdate, OutgoingRoute) ), ('Peer cannot process object: %s in its outgoing queue' % outgoing_msg) # Send msg. to peer. - if isinstance(outgoing_msg, messages.RouteRefresh): + if isinstance(outgoing_msg, BGPRouteRefresh): self._send_outgoing_route_refresh_msg(outgoing_msg) elif isinstance(outgoing_msg, OutgoingRoute): self._send_outgoing_route(outgoing_msg) # EOR are enqueued as plain Update messages. - elif isinstance(outgoing_msg, messages.Update): + elif isinstance(outgoing_msg, BGPUpdate): self._protocol.send(outgoing_msg) LOG.debug('Update %s>> %s' % (self._neigh_conf.ip_address, outgoing_msg)) @@ -523,17 +551,17 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # We ignore request for route_family not valid # for current session. self._protocol.is_mbgp_cap_valid(route_family))): - rr_req = messages.RouteRefresh(route_family) + rr_req = BGPRouteRefresh(route_family.afi, route_family.safi) self.enque_outgoing_msg(rr_req) LOG.debug('Enqueued Route Refresh message to ' 'peer %s for rf: %s' % (self, route_family)) def enque_end_of_rib(self, route_family): - pattr_map = {} # MP_UNREACH_NLRI Attribute. - mpunreach_attr = pathattr.MpUnreachNlri(route_family, []) - pattr_map[pathattr.MpUnreachNlri.ATTR_NAME] = mpunreach_attr - update = messages.Update(pathattr_map=pattr_map) + mpunreach_attr = BGPPathAttributeMpUnreachNLRI(route_family.afi, + route_family.safi, + []) + update = BGPUpdate(path_attributes=[mpunreach_attr]) self.enque_outgoing_msg(update) def _session_next_hop(self, route_family): @@ -546,9 +574,13 @@ class Peer(Source, Sink, NeighborConfListener, Activity): """ # By default we use BGPS's interface IP with this peer as next_hop. next_hop = self._neigh_conf.host_bind_ip - if route_family == nlri.RF_IPv6_VPN: + if route_family == RF_IPv6_VPN: # Next hop ipv4_mapped ipv6 - next_hop = nlri.ipv4_mapped_ipv6(next_hop) + def _ipv4_mapped_ipv6(ipv4): + from netaddr import IPAddress + return str(IPAddress(ipv4).ipv6()) + + next_hop = _ipv4_mapped_ipv6(next_hop) return next_hop @@ -556,8 +588,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): """Construct update message with Outgoing-routes path attribute appropriately cloned/copied/updated. """ - is_bgp4_format = outgoing_route.bgp4_format - if is_bgp4_format: + if self._neigh_conf.cap_mbgp_ipv4: update = self._construct_bgp4_update(outgoing_route) else: update = self._construct_mpbgp_update(outgoing_route) @@ -569,10 +600,10 @@ class Peer(Source, Sink, NeighborConfListener, Activity): path = outgoing_route.path # Get copy of path's path attributes. pathattr_map = path.pathattr_map - new_pathattr_map = OrderedDict() + new_pathattr = [] if path.is_withdraw: - update = messages.Update(withdraw_list=path.nlri) + update = BGPUpdate(withdrawn_routes=[path.nlri]) return update else: # Supported and un-supported/unknown attributes. @@ -595,19 +626,19 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # If the path came from a bgp peer and not from NC, according # to RFC 4271 we should not modify next_hop. next_hop = path.nexthop - nexthop_attr = pathattr.NextHop(next_hop) + nexthop_attr = BGPPathAttributeNextHop(next_hop) assert nexthop_attr, 'Missing NEXTHOP mandatory attribute.' # ORIGIN Attribute. # According to RFC this attribute value SHOULD NOT be changed by # any other speaker. - origin_attr = pathattr_map.get(pathattr.Origin.ATTR_NAME) + origin_attr = pathattr_map.get(BGP_ATTR_TYPE_ORIGIN) assert origin_attr, 'Missing ORIGIN mandatory attribute.' # AS_PATH Attribute. # Construct AS-path-attr using paths aspath attr. with local AS as # first item. - path_aspath = pathattr_map.get(pathattr.AsPath.ATTR_NAME) + path_aspath = pathattr_map.get(BGP_ATTR_TYPE_AS_PATH) assert path_aspath, 'Missing AS_PATH mandatory attribute.' # Deep copy aspath_attr value path_seg_list = path_aspath.path_seg_list @@ -616,7 +647,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # When a given BGP speaker advertises the route to an internal # peer, the advertising speaker SHALL NOT modify the AS_PATH # attribute associated with the route. - aspath_attr = pathattr.AsPath(path_seg_list) + aspath_attr = BGPPathAttributeAsPath(path_seg_list) else: # When a given BGP speaker advertises the route to an external # peer, the advertising speaker updates the AS_PATH attribute @@ -644,15 +675,16 @@ class Peer(Source, Sink, NeighborConfListener, Activity): path_seg_list[0].insert(0, self._core_service.asn) else: path_seg_list.insert(0, [self._core_service.asn]) - aspath_attr = pathattr.AsPath(path_seg_list) + aspath_attr = BGPPathAttributeAsPath(path_seg_list) # MULTI_EXIT_DISC Attribute. # For eBGP session we can send multi-exit-disc if configured. multi_exit_disc = None if self.is_ebgp_peer(): - multi_exit_disc = pathattr_map.get(pathattr.Med.ATTR_NAME) + multi_exit_disc = pathattr_map.get( + BGP_ATTR_TYPE_MULTI_EXIT_DISC) if not multi_exit_disc and self._neigh_conf.multi_exit_disc: - multi_exit_disc = pathattr.Med( + multi_exit_disc = BGPPathAttributeMultiExitDisc( self._neigh_conf.multi_exit_disc ) @@ -660,15 +692,15 @@ class Peer(Source, Sink, NeighborConfListener, Activity): if not self.is_ebgp_peer(): # For iBGP peers we are required to send local-pref attribute # for connected or local prefixes. We send default local-pref. - localpref_attr = pathattr.LocalPref(100) + localpref_attr = BGPPathAttributeLocalPref(100) # COMMUNITY Attribute. - community_attr = pathattr_map.get(pathattr.Community.ATTR_NAME) + community_attr = pathattr_map.get(BGP_ATTR_TYPE_COMMUNITIES) # EXTENDED COMMUNITY Attribute. # Construct ExtCommunity path-attr based on given. path_extcomm_attr = pathattr_map.get( - pathattr.ExtCommunity.ATTR_NAME + BGP_ATTR_TYPE_EXTENDED_COMMUNITIES ) if path_extcomm_attr: # SOO list can be configured per VRF and/or per Neighbor. @@ -676,7 +708,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): soo_list = path_extcomm_attr.soo_list if self._neigh_conf.soo_list: soo_list.extend(self._neigh_conf.soo_list) - extcomm_attr = pathattr.ExtCommunity( + extcomm_attr = BGPPathAttributeExtendedCommunities( path_extcomm_attr.rt_list, soo_list ) @@ -688,22 +720,22 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # Ordering path attributes according to type as RFC says. We set # MPReachNLRI first as advised by experts as a new trend in BGP # implementation. - new_pathattr_map[pathattr.NextHop.ATTR_NAME] = nexthop_attr - new_pathattr_map[pathattr.Origin.ATTR_NAME] = origin_attr - new_pathattr_map[pathattr.AsPath.ATTR_NAME] = aspath_attr + new_pathattr.append(nexthop_attr) + new_pathattr.append(origin_attr) + new_pathattr.append(aspath_attr) if multi_exit_disc: - new_pathattr_map[pathattr.Med.ATTR_NAME] = multi_exit_disc + new_pathattr.append(multi_exit_disc) if localpref_attr: - new_pathattr_map[pathattr.LocalPref.ATTR_NAME] = localpref_attr + new_pathattr.append(localpref_attr) if community_attr: - new_pathattr_map[pathattr.Community.ATTR_NAME] = community_attr + new_pathattr.append(community_attr) if extcomm_attr: - new_pathattr_map[pathattr.ExtCommunity.ATTR_NAME] =\ - extcomm_attr + new_pathattr.append(extcomm_attr) if unkown_opttrans_attrs: - new_pathattr_map.update(unkown_opttrans_attrs) - update = messages.Update(pathattr_map=new_pathattr_map, - nlri_list=nlri_list) + new_pathattr.extend(unkown_opttrans_attrs.values()) + + update = BGPUpdate(path_attributes=new_pathattr, + nlri=nlri_list) return update def _construct_mpbgp_update(self, outgoing_route): @@ -715,16 +747,16 @@ class Peer(Source, Sink, NeighborConfListener, Activity): path = outgoing_route.path # Get copy of path's path attributes. pathattr_map = path.pathattr_map - new_pathattr_map = OrderedDict() + new_pathattr = [] # If this is withdraw update we copy MpUnReach path-attribute and # create new Update message. if path.is_withdraw: # MP_UNREACH_NLRI Attribute. - mpunreach_attr = pathattr.MpUnreachNlri( - path.route_family, [path.nlri] + mpunreach_attr = BGPPathAttributeMpUnreachNLRI( + path.route_family.afi, path.route_family.safi, [path.nlri] ) - new_pathattr_map[pathattr.MpUnreachNlri.ATTR_NAME] = mpunreach_attr + new_pathattr.append(mpunreach_attr) else: # Supported and un-supported/unknown attributes. origin_attr = None @@ -746,20 +778,23 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # to RFC 4271 we should not modify next_hop. next_hop = path.nexthop # We construct mpreach-nlri attribute. - mpnlri_attr = pathattr.MpReachNlri( - path.route_family, next_hop, [path.nlri] + mpnlri_attr = BGPPathAttributeMpReachNLRI( + path.route_family.afi, + path.route_family.safi, + next_hop, + [path.nlri] ) # ORIGIN Attribute. # According to RFC this attribute value SHOULD NOT be changed by # any other speaker. - origin_attr = pathattr_map.get(pathattr.Origin.ATTR_NAME) + origin_attr = pathattr_map.get(BGP_ATTR_TYPE_ORIGIN) assert origin_attr, 'Missing ORIGIN mandatory attribute.' # AS_PATH Attribute. # Construct AS-path-attr using paths aspath attr. with local AS as # first item. - path_aspath = pathattr_map.get(pathattr.AsPath.ATTR_NAME) + path_aspath = pathattr_map.get(BGP_ATTR_TYPE_AS_PATH) assert path_aspath, 'Missing AS_PATH mandatory attribute.' # Deep copy aspath_attr value path_seg_list = path_aspath.path_seg_list @@ -768,7 +803,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # When a given BGP speaker advertises the route to an internal # peer, the advertising speaker SHALL NOT modify the AS_PATH # attribute associated with the route. - aspath_attr = pathattr.AsPath(path_seg_list) + aspath_attr = BGPPathAttributeAsPath(path_seg_list) else: # When a given BGP speaker advertises the route to an external # peer, the advertising speaker updates the AS_PATH attribute @@ -796,13 +831,14 @@ class Peer(Source, Sink, NeighborConfListener, Activity): path_seg_list[0].insert(0, self._core_service.asn) else: path_seg_list.insert(0, [self._core_service.asn]) - aspath_attr = pathattr.AsPath(path_seg_list) + aspath_attr = BGPPathAttributeAsPath(path_seg_list) # MULTI_EXIT_DISC Attribute. # For eBGP session we can send multi-exit-disc if configured. multi_exit_disc = None if self.is_ebgp_peer(): - multi_exit_disc = pathattr_map.get(pathattr.Med.ATTR_NAME) + multi_exit_disc = pathattr_map.get( + BGP_ATTR_TYPE_MULTI_EXIT_DISC) # LOCAL_PREF Attribute. if not self.is_ebgp_peer(): @@ -811,12 +847,12 @@ class Peer(Source, Sink, NeighborConfListener, Activity): localpref_attr = pathattr.LocalPref(100) # COMMUNITY Attribute. - community_attr = pathattr_map.get(pathattr.Community.ATTR_NAME) + community_attr = pathattr_map.get(BGP_ATTR_TYPE_COMMUNITIES) # EXTENDED COMMUNITY Attribute. # Construct ExtCommunity path-attr based on given. path_extcomm_attr = pathattr_map.get( - pathattr.ExtCommunity.ATTR_NAME + BGP_ATTR_TYPE_EXTENDED_COMMUNITIES ) if path_extcomm_attr: # SOO list can be configured per VRF and/or per Neighbor. @@ -824,9 +860,8 @@ class Peer(Source, Sink, NeighborConfListener, Activity): soo_list = path_extcomm_attr.soo_list if self._neigh_conf.soo_list: soo_list.extend(self._neigh_conf.soo_list) - extcomm_attr = pathattr.ExtCommunity( - path_extcomm_attr.rt_list, - soo_list + extcomm_attr = BGPPathAttributeExtendedCommunities( + path_extcomm_attr.rt_list+soo_list ) # UNKOWN Attributes. @@ -836,22 +871,21 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # Ordering path attributes according to type as RFC says. We set # MPReachNLRI first as advised by experts as a new trend in BGP # implementation. - new_pathattr_map[pathattr.MpReachNlri.ATTR_NAME] = mpnlri_attr - new_pathattr_map[pathattr.Origin.ATTR_NAME] = origin_attr - new_pathattr_map[pathattr.AsPath.ATTR_NAME] = aspath_attr + new_pathattr.append(mpnlri_attr) + new_pathattr.append(origin_attr) + new_pathattr.append(aspath_attr) if multi_exit_disc: - new_pathattr_map[pathattr.Med.ATTR_NAME] = multi_exit_disc + new_pathattr.append(multi_exit_disc) if localpref_attr: - new_pathattr_map[pathattr.LocalPref.ATTR_NAME] = localpref_attr + new_pathattr.append(localpref_attr) if community_attr: - new_pathattr_map[pathattr.Community.ATTR_NAME] = community_attr + new_pathattr.append(community_attr) if extcomm_attr: - new_pathattr_map[pathattr.ExtCommunity.ATTR_NAME] =\ - extcomm_attr + new_pathattr.append(extcomm_attr) if unkown_opttrans_attrs: - new_pathattr_map.update(unkown_opttrans_attrs) + new_pathattr.extend(unkown_opttrans_attrs.values()) - update = messages.Update(pathattr_map=new_pathattr_map) + update = BGPUpdate(path_attributes=new_pathattr) return update def _connect_loop(self, client_factory): @@ -923,8 +957,8 @@ class Peer(Source, Sink, NeighborConfListener, Activity): LOG.debug('Processing of outgoing msg. started for %s.' % self) def _send_collision_err_and_stop(self, protocol): - code = exceptions.CollisionResolution.CODE - subcode = exceptions.CollisionResolution.SUB_CODE + code = BGP_ERROR_CEASE + subcode = BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION self._signal_bus.bgp_error(self, code, subcode, None) protocol.send_notification(code, subcode) protocol.stop() @@ -1011,12 +1045,22 @@ class Peer(Source, Sink, NeighborConfListener, Activity): asnum = self._common_conf.local_as bgpid = self._common_conf.router_id holdtime = self._neigh_conf.hold_time - open_msg = messages.Open( - const.BGP_VERSION_NUM, - asnum, - holdtime, - bgpid, - self._neigh_conf.get_configured_capabilites() + + def flatten(L): + if isinstance(L, list): + for i in xrange(len(L)): + for e in flatten(L[i]): + yield e + else: + yield L + opts = list(flatten( + self._neigh_conf.get_configured_capabilites().values())) + open_msg = BGPOpen( + my_as=asnum, + bgp_identifier=bgpid, + version=const.BGP_VERSION_NUM, + hold_time=holdtime, + opt_param=opts ) return open_msg @@ -1028,35 +1072,35 @@ class Peer(Source, Sink, NeighborConfListener, Activity): library. """ # TODO(PH): finish providing implementation, currently low priority - assert update_msg.TYPE_CODE == messages.Update.TYPE_CODE + assert update_msg.type == BGP_MSG_UPDATE # An UPDATE message may be received only in the Established state. # Receiving an UPDATE message in any other state is an error. if self.state.bgp_state != const.BGP_FSM_ESTABLISHED: LOG.error('Received UPDATE message when not in ESTABLISHED' ' state.') - raise exceptions.FiniteStateMachineError() + raise bgp.FiniteStateMachineError() mp_reach_attr = update_msg.get_path_attr( - pathattr.MpReachNlri.ATTR_NAME + BGP_ATTR_TYPE_MP_REACH_NLRI ) mp_unreach_attr = update_msg.get_path_attr( - pathattr.MpUnreachNlri.ATTR_NAME + BGP_ATTR_TYPE_MP_UNREACH_NLRI ) # non-MPBGP Update msg. if not (mp_reach_attr or mp_unreach_attr): LOG.info('Received UPDATE msg. with no MpReachNlri or ' 'MpUnReachNlri attribute.') - if not self.is_mpbgp_cap_valid(nlri.RF_IPv4_UC): + if not self.is_mpbgp_cap_valid(RF_IPv4_UC): LOG.error('Got UPDATE message with un-available' - ' afi/safi %s' % nlri.RF_IPv4_UC) - nlri_list = update_msg.nlri_list + ' afi/safi %s' % RF_IPv4_UC) + nlri_list = update_msg.nlri if len(nlri_list) > 0: # Check for missing well-known mandatory attributes. - aspath = update_msg.get_path_attr(pathattr.AsPath.ATTR_NAME) + aspath = update_msg.get_path_attr(BGP_ATTR_TYPE_AS_PATH) if not aspath: - raise exceptions.MissingWellKnown( - pathattr.AsPath.TYPE_CODE) + raise bgp.MissingWellKnown( + BGP_ATTR_TYPE_AS_PATH) # We do not have a setting to enable/disable first-as check. # We by default do first-as check below. @@ -1064,17 +1108,15 @@ class Peer(Source, Sink, NeighborConfListener, Activity): not aspath.has_matching_leftmost(self.remote_as)): LOG.error('First AS check fails. Raise appropriate' ' exception.') - raise exceptions.MalformedAsPath() + raise bgp.MalformedAsPath() - origin = update_msg.get_path_attr(pathattr.Origin.ATTR_NAME) + origin = update_msg.get_path_attr(BGP_ATTR_TYPE_ORIGIN) if not origin: - raise exceptions.MissingWellKnown( - pathattr.Origin.TYPE_CODE) + raise bgp.MissingWellKnown(BGP_ATTR_TYPE_ORIGIN) - nexthop = update_msg.get_path_attr(pathattr.NextHop.ATTR_NAME) + nexthop = update_msg.get_path_attr(BGP_ATTR_TYPE_NEXT_HOP) if not nexthop: - raise exceptions.MissingWellKnown( - pathattr.NextHop.TYPE_CODE) + raise bgp.MissingWellKnown(BGP_ATTR_TYPE_NEXT_HOP) return True @@ -1084,7 +1126,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): LOG.error('Got UPDATE message with un-available afi/safi for' ' MP_UNREACH path attribute (non-negotiated' ' afi/safi) %s' % mp_unreach_attr.route_family) - # raise exceptions.OptAttrError() + # raise bgp.OptAttrError() if mp_reach_attr: # Check if received MP_REACH path attribute is of available @@ -1093,23 +1135,23 @@ class Peer(Source, Sink, NeighborConfListener, Activity): LOG.error('Got UPDATE message with un-available afi/safi for' ' MP_UNREACH path attribute (non-negotiated' ' afi/safi) %s' % mp_reach_attr.route_family) - # raise exceptions.OptAttrError() + # raise bgp.OptAttrError() # Check for missing well-known mandatory attributes. - aspath = update_msg.get_path_attr(pathattr.AsPath.ATTR_NAME) + aspath = update_msg.get_path_attr(BGP_ATTR_TYPE_AS_PATH) if not aspath: - raise exceptions.MissingWellKnown(pathattr.AsPath.TYPE_CODE) + raise bgp.MissingWellKnown(BGP_ATTR_TYPE_AS_PATH) # We do not have a setting to enable/disable first-as check. # We by default do first-as check below. if (self.is_ebgp_peer() and not aspath.has_matching_leftmost(self.remote_as)): LOG.error('First AS check fails. Raise appropriate exception.') - raise exceptions.MalformedAsPath() + raise bgp.MalformedAsPath() - origin = update_msg.get_path_attr(pathattr.Origin.ATTR_NAME) + origin = update_msg.get_path_attr(BGP_ATTR_TYPE_ORIGIN) if not origin: - raise exceptions.MissingWellKnown(pathattr.Origin.TYPE_CODE) + raise bgp.MissingWellKnown(BGP_ATTR_TYPE_ORIGIN) # Validate Next hop. # TODO(PH): Currently ignore other cases. @@ -1142,15 +1184,13 @@ class Peer(Source, Sink, NeighborConfListener, Activity): return # Increment count of update received. - mp_reach_attr = update_msg.get_path_attr( - pathattr.MpReachNlri.ATTR_NAME - ) + mp_reach_attr = update_msg.get_path_attr(BGP_ATTR_TYPE_MP_REACH_NLRI) mp_unreach_attr = update_msg.get_path_attr( - pathattr.MpUnreachNlri.ATTR_NAME + BGP_ATTR_TYPE_MP_UNREACH_NLRI ) - nlri_list = update_msg.nlri_list - withdraw_list = update_msg.withdraw_list + nlri_list = update_msg.nlri + withdraw_list = update_msg.withdrawn_routes if mp_reach_attr: # Extract advertised paths from given message. @@ -1181,7 +1221,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): """ umsg_pattrs = update_msg.pathattr_map - msg_rf = nlri.RF_IPv4_UC + msg_rf = RF_IPv4_UC # Check if this route family is among supported route families. if msg_rf not in SUPPORTED_GLOBAL_RF: LOG.info(('Received route for route family %s which is' @@ -1189,16 +1229,16 @@ class Peer(Source, Sink, NeighborConfListener, Activity): (msg_rf, update_msg)) return - aspath = umsg_pattrs.get(pathattr.AsPath.ATTR_NAME) + aspath = umsg_pattrs.get(BGP_ATTR_TYPE_AS_PATH) # Check if AS_PATH has loops. if aspath.has_local_as(self._common_conf.local_as): LOG.error('Update message AS_PATH has loops. Ignoring this' ' UPDATE. %s' % update_msg) return - next_hop = update_msg.get_path_attr(pathattr.NextHop.ATTR_NAME) + next_hop = update_msg.get_path_attr(BGP_ATTR_TYPE_NEXT_HOP) # Nothing to do if we do not have any new NLRIs in this message. - msg_nlri_list = update_msg.nlri_list + msg_nlri_list = update_msg.nlri if not msg_nlri_list: LOG.debug('Update message did not have any new MP_REACH_NLRIs.') return @@ -1240,7 +1280,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): Extracted withdraws are added to appropriate *Destination* for further processing. """ - msg_rf = nlri.RF_IPv4_UC + msg_rf = RF_IPv4_UC # Check if this route family is among supported route families. if msg_rf not in SUPPORTED_GLOBAL_RF: LOG.info( @@ -1280,7 +1320,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): processing. """ umsg_pattrs = update_msg.pathattr_map - mpreach_nlri_attr = umsg_pattrs.pop(pathattr.MpReachNlri.ATTR_NAME) + mpreach_nlri_attr = umsg_pattrs.pop(BGP_ATTR_TYPE_MP_REACH_NLRI) assert mpreach_nlri_attr msg_rf = mpreach_nlri_attr.route_family @@ -1291,17 +1331,17 @@ class Peer(Source, Sink, NeighborConfListener, Activity): (msg_rf, update_msg)) return - aspath = umsg_pattrs.get(pathattr.AsPath.ATTR_NAME) + aspath = umsg_pattrs.get(BGP_ATTR_TYPE_AS_PATH) # Check if AS_PATH has loops. if aspath.has_local_as(self._common_conf.local_as): LOG.error('Update message AS_PATH has loops. Ignoring this' ' UPDATE. %s' % update_msg) return - if msg_rf in (nlri.RF_IPv4_VPN, nlri.RF_IPv6_UC): + if msg_rf in (RF_IPv4_VPN, RF_IPv6_UC): # Check if we have Extended Communities Attribute. # TODO(PH): Check if RT_NLRI afi/safi will ever have this attribute - ext_comm_attr = umsg_pattrs.get(pathattr.ExtCommunity.ATTR_NAME) + ext_comm_attr = umsg_pattrs.get(BGP_ATTR_TYPE_EXTENDED_COMMUNITIES) # Check if we have at-least one RT is of interest to us. if not ext_comm_attr: LOG.info('Missing Extended Communities Attribute. ' @@ -1328,7 +1368,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): next_hop = mpreach_nlri_attr.next_hop # Nothing to do if we do not have any new NLRIs in this message. - msg_nlri_list = mpreach_nlri_attr.nlri_list + msg_nlri_list = mpreach_nlri_attr.nlri if not msg_nlri_list: LOG.debug('Update message did not have any new MP_REACH_NLRIs.') return @@ -1342,7 +1382,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): nexthop=next_hop ) LOG.debug('Extracted paths from Update msg.: %s' % new_path) - if msg_rf == nlri.RF_RTC_UC \ + if msg_rf == RF_RTC_UC \ and self._init_rtc_nlri_path is not None: self._init_rtc_nlri_path.append(new_path) else: @@ -1408,7 +1448,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # assert (route_family in SUPPORTED_GLOBAL_RF) # assert self.is_mbgp_cap_valid(route_family) - if route_family == nlri.RF_RTC_UC: + if route_family == RF_RTC_UC: self._unschedule_sending_init_updates() # Learn all rt_nlri at the same time As RT are learned and RT @@ -1434,19 +1474,19 @@ class Peer(Source, Sink, NeighborConfListener, Activity): KEEPALIVE, UPDATE and ROUTE_REFRESH messages. UPDATE and ROUTE_REFRESH messages are handled only after session is established. """ - if msg.MSG_NAME == messages.Keepalive.MSG_NAME: + if msg.type == BGP_MSG_KEEPALIVE: # If we receive a Keep Alive message in open_confirm state, we # transition to established state. if self.state.bgp_state == const.BGP_FSM_OPEN_CONFIRM: self.state.bgp_state = const.BGP_FSM_ESTABLISHED self._enqueue_init_updates() - elif msg.MSG_NAME == messages.Update.MSG_NAME: + elif msg.type == BGP_MSG_UPDATE: assert self.state.bgp_state == const.BGP_FSM_ESTABLISHED # Will try to process this UDPATE message further self._handle_update_msg(msg) - elif msg.MSG_NAME == messages.RouteRefresh.MSG_NAME: + elif msg.type == BGP_MSG_ROUTE_REFRESH: # If its route-refresh message assert self.state.bgp_state == const.BGP_FSM_ESTABLISHED self._handle_route_refresh_msg(msg) @@ -1456,7 +1496,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # nothing is done inside peer, so should not see them here. raise ValueError('Peer does not support handling of %s' ' message during % state' % - (msg.MSG_NAME, self.state.bgp_state())) + (msg, self.state.bgp_state())) def _handle_err_sor_msg(self, afi, safi): # Check if ERR capability is enabled for this peer. @@ -1474,7 +1514,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): if rst != 0: # Set a timer to clean the stale paths at configured time. # Clean/track inconsistent/stale routes. - route_family = nlri.get_rf(afi, safi) + route_family = RouteFamily(afi, safi) if route_family in SUPPORTED_GLOBAL_RF: self._refresh_stalepath_timer = self._spawn_after( 'err-refresh-stale-path-timer', rst, @@ -1498,7 +1538,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # If this is end of RIB (EOR) message. elif demarcation == 2: # Clean/track inconsistent/stale routes. - route_family = nlri.get_rf(afi, safi) + route_family = RouteFamily(afi, safi) if route_family in SUPPORTED_GLOBAL_RF: tm = self._core_service.table_manager tm.clean_stale_routes(self, route_family) @@ -1508,7 +1548,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): demarcation) def _handle_route_refresh_req(self, afi, safi): - rr_af = nlri.get_rf(afi, safi) + rr_af = RouteFamily(afi, safi) self.state.incr(PeerCounterNames.RECV_REFRESH) # Check if peer has asked for route-refresh for af that was advertised @@ -1524,7 +1564,9 @@ class Peer(Source, Sink, NeighborConfListener, Activity): sor = None if self._protocol.is_enhanced_rr_cap_valid(): # If enhanced route-refresh is valid/enabled, enqueue SOR. - sor = messages.RouteRefresh(af, demarcation=1) + afi = af.afi + safi = af.safi + sor = BGPRouteRefresh(afi, safi, reserved=1) self.enque_first_outgoing_msg(sor) # Ask core to re-send sent routes @@ -1539,7 +1581,9 @@ class Peer(Source, Sink, NeighborConfListener, Activity): sent. """ if self._protocol.is_enhanced_rr_cap_valid() and not sor.eor_sent: - eor = messages.RouteRefresh(sor.route_family, demarcation=2) + afi = sor.route_family.afi + safi = sor.route_family.safi + eor = BGPRouteRefresh(afi, safi, reserved=2) self.enque_outgoing_msg(eor) sor.eor_sent = True @@ -1589,7 +1633,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): def _enqueue_init_updates(self): """Enqueues current routes to be shared with this peer.""" assert self.state.bgp_state == const.BGP_FSM_ESTABLISHED - if self.is_mbgp_cap_valid(nlri.RF_RTC_UC): + if self.is_mbgp_cap_valid(RF_RTC_UC): # Enqueues all best-RTC_NLRIs to be sent as initial update to this # peer. self._peer_manager.comm_all_rt_nlris(self) @@ -1610,7 +1654,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): ' 1/132') # We will enqueue best path from all global destination. for route_family, table in global_tables.iteritems(): - if route_family == nlri.RF_RTC_UC: + if route_family == RF_RTC_UC: continue if self.is_mbgp_cap_valid(route_family): for dest in table.itervalues(): @@ -1643,8 +1687,8 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # If RTC capability is available and path afi/saif is other than RT # nlri - if path_rf != nlri.RF_RTC_UC and \ - self.is_mpbgp_cap_valid(nlri.RF_RTC_UC): + if path_rf != RF_RTC_UC and \ + self.is_mpbgp_cap_valid(RF_RTC_UC): rtfilter = self._peer_manager.curr_peer_rtfilter(self) # If peer does not have any rtfilter or if rtfilter does not have # any RTs common with path RTs we do not share this path with the @@ -1657,14 +1701,14 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # Transmit side loop detection: We check if leftmost AS matches # peers AS, if so we do not send UPDATE message to this peer. - as_path = path.get_pattr(pathattr.AsPath.ATTR_NAME) + as_path = path.get_pattr(BGP_ATTR_TYPE_AS_PATH) if as_path and as_path.has_matching_leftmost(self.remote_as): LOG.debug('Skipping sending path as AS_PATH has peer AS %s' % self.remote_as) return if self._neigh_conf.multi_exit_disc: - med_attr = path.get_pattr(pathattr.Med.ATTR_NAME) + med_attr = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC) if not med_attr: path = bgp_utils.clone_path_and_update_med_for_target_neighbor( path, @@ -1675,10 +1719,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): if path.source is None: # Construct OutgoingRoute specific for this peer and put it in # its sink. - bgp4_format = False - if self._neigh_conf.cap_mbgp_ipv4: - bgp4_format = True - outgoing_route = OutgoingRoute(path, bgp4_format=bgp4_format) + outgoing_route = OutgoingRoute(path) self.enque_outgoing_msg(outgoing_route) # If path from a bgp-peer is new best path, we share it with @@ -1698,10 +1739,10 @@ class Peer(Source, Sink, NeighborConfListener, Activity): # If new best path has community attribute, it should be taken into # account when sending UPDATE to peers. - comm_attr = path.get_pattr(pathattr.Community.ATTR_NAME) + comm_attr = path.get_pattr(BGP_ATTR_TYPE_COMMUNITIES) if comm_attr: comm_attr_na = comm_attr.has_comm_attr( - pathattr.Community.NO_ADVERTISE + BGPPathAttributeCommunities.NO_ADVERTISE ) # If we have NO_ADVERTISE attribute present, we do not send # UPDATE to any peers @@ -1712,10 +1753,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity): return comm_attr_ne = comm_attr.has_comm_attr( - pathattr.Community.NO_EXPORT + BGPPathAttributeCommunities.NO_EXPORT ) comm_attr_nes = comm_attr.has_comm_attr( - pathattr.Community.NO_EXPORT_SUBCONFED) + BGPPathAttributeCommunities.NO_EXPORT_SUBCONFED + ) # If NO_EXPORT_SUBCONFED/NO_EXPORT is one of the attribute, we # do not advertise to eBGP peers as we do not have any # confederation feature at this time. diff --git a/ryu/services/protocols/bgp/processor.py b/ryu/services/protocols/bgp/processor.py index db5ae9bf..e56224de 100644 --- a/ryu/services/protocols/bgp/processor.py +++ b/ryu/services/protocols/bgp/processor.py @@ -18,12 +18,6 @@ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_RTC_UC -from ryu.services.protocols.bgp.protocols.bgp.pathattr import AsPath -from ryu.services.protocols.bgp.protocols.bgp.pathattr import LocalPref -from ryu.services.protocols.bgp.protocols.bgp.pathattr import Med -from ryu.services.protocols.bgp.protocols.bgp.pathattr import Origin - from ryu.services.protocols.bgp.base import Activity from ryu.services.protocols.bgp.base import add_bgp_error_metadata from ryu.services.protocols.bgp.base import BGP_PROCESSOR_ERROR_CODE @@ -31,6 +25,14 @@ from ryu.services.protocols.bgp.base import BGPSException from ryu.services.protocols.bgp.utils import circlist from ryu.services.protocols.bgp.utils.evtlet import EventletIOFactory +from ryu.lib.packet.bgp import RF_RTC_UC +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_LOCAL_PREF +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN +from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_IGP +from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_EGP +from ryu.lib.packet.bgp import BGP_ATTR_ORIGIN_INCOMPLETE LOG = logging.getLogger('bgpspeaker.processor') @@ -150,9 +152,9 @@ class BgpProcessor(Activity): # Wake-up processing thread if sleeping. self.dest_que_evt.set() -#============================================================================== +# ============================================================================= # Best path computation related utilities. -#============================================================================== +# ============================================================================= # Various reasons a path is chosen as best path. BPR_UNKNOWN = 'Unknown' @@ -289,8 +291,8 @@ def _cmp_by_local_pref(path1, path2): # TODO(PH): Revisit this when BGPS has concept of policy to be applied to # in-bound NLRIs. # Default local-pref values is 100 - lp1 = path1.get_pattr(LocalPref.ATTR_NAME) - lp2 = path2.get_pattr(LocalPref.ATTR_NAME) + lp1 = path1.get_pattr(BGP_ATTR_TYPE_LOCAL_PREF) + lp2 = path2.get_pattr(BGP_ATTR_TYPE_LOCAL_PREF) if not (lp1 and lp2): return None @@ -335,8 +337,8 @@ def _cmp_by_aspath(path1, path2): Shortest as-path length is preferred. If both path have same lengths, we return None. """ - as_path1 = path1.get_pattr(AsPath.ATTR_NAME) - as_path2 = path2.get_pattr(AsPath.ATTR_NAME) + as_path1 = path1.get_pattr(BGP_ATTR_TYPE_AS_PATH) + as_path2 = path2.get_pattr(BGP_ATTR_TYPE_AS_PATH) assert as_path1 and as_path2 l1 = as_path1.get_as_path_len() l2 = as_path2.get_as_path_len() @@ -356,18 +358,18 @@ def _cmp_by_origin(path1, path2): If both paths have same origin, we return None. """ def get_origin_pref(origin): - if origin.value == Origin.IGP: + if origin.value == BGP_ATTR_ORIGIN_IGP: return 3 - elif origin.value == Origin.EGP: + elif origin.value == BGP_ATTR_ORIGIN_EGP: return 2 - elif origin.value == Origin.INCOMPLETE: + elif origin.value == BGP_ATTR_ORIGIN_INCOMPLETE: return 1 else: LOG.error('Invalid origin value encountered %s.' % origin) return 0 - origin1 = path1.get_pattr(Origin.ATTR_NAME) - origin2 = path2.get_pattr(Origin.ATTR_NAME) + origin1 = path1.get_pattr(BGP_ATTR_TYPE_ORIGIN) + origin2 = path2.get_pattr(BGP_ATTR_TYPE_ORIGIN) assert origin1 is not None and origin2 is not None # If both paths have same origins @@ -394,7 +396,7 @@ def _cmp_by_med(path1, path2): RFC says lower MED is preferred over higher MED value. """ def get_path_med(path): - med = path.get_pattr(Med.ATTR_NAME) + med = path.get_pattr(BGP_ATTR_TYPE_MULTI_EXIT_DISC) if not med: return 0 return med.value diff --git a/ryu/services/protocols/bgp/rtconf/base.py b/ryu/services/protocols/bgp/rtconf/base.py index 36febbc6..7b625fd3 100644 --- a/ryu/services/protocols/bgp/rtconf/base.py +++ b/ryu/services/protocols/bgp/rtconf/base.py @@ -28,8 +28,6 @@ from ryu.services.protocols.bgp.base import BGPSException from ryu.services.protocols.bgp.base import get_validator from ryu.services.protocols.bgp.base import RUNTIME_CONF_ERROR_CODE from ryu.services.protocols.bgp.base import validate - -from ryu.services.protocols.bgp.protocols.bgp.pathattr import ExtCommunity from ryu.services.protocols.bgp.utils import validation from ryu.services.protocols.bgp.utils.validation import is_valid_old_asn @@ -73,9 +71,9 @@ MAX_NUM_EXPORT_RT = 250 MAX_NUM_SOO = 10 -#============================================================================== +# ============================================================================= # Runtime configuration errors or exceptions. -#============================================================================== +# ============================================================================= @add_bgp_error_metadata(code=RUNTIME_CONF_ERROR_CODE, sub_code=1, def_desc='Error with runtime-configuration.') @@ -139,9 +137,9 @@ class ConfigValueError(RuntimeConfigError): super(ConfigValueError, self).__init__(desc=kwargs.get('desc')) -#============================================================================== +# ============================================================================= # Configuration base classes. -#============================================================================== +# ============================================================================= class BaseConf(object): """Base class for a set of configuration values. @@ -225,8 +223,8 @@ class BaseConf(object): self._settings[req_attr] = req_attr_value def add_listener(self, evt, callback): -# if (evt not in self.get_valid_evts()): -# raise RuntimeConfigError(desc=('Unknown event %s' % evt)) + # if (evt not in self.get_valid_evts()): + # raise RuntimeConfigError(desc=('Unknown event %s' % evt)) listeners = self._listeners.get(evt, None) if not listeners: @@ -523,9 +521,9 @@ class ConfEvent(object): (self.src, self.name, self.value)) -#============================================================================== +# ============================================================================= # Runtime configuration setting validators and their registry. -#============================================================================== +# ============================================================================= @validate(name=ConfWithId.ID) def validate_conf_id(identifier): @@ -658,9 +656,7 @@ def validate_soo_list(soo_list): if not (len(soo_list) <= MAX_NUM_SOO): raise ConfigValueError(desc='Max. SOO is limited to %s' % MAX_NUM_SOO) - try: - ExtCommunity.validate_supported_attributes(soo_list) - except ValueError: + if not all(validation.is_valid_ext_comm_attr(attr) for attr in soo_list): raise ConfigValueError(conf_name=SITE_OF_ORIGINS, conf_value=soo_list) # Check if we have duplicates @@ -691,9 +687,9 @@ def validate_advertise_peer_as(advertise_peer_as): return advertise_peer_as -#============================================================================== +# ============================================================================= # Other utils. -#============================================================================== +# ============================================================================= def compute_optional_conf(conf_name, default_value, **all_config): """Returns *conf_name* settings if provided in *all_config*, else returns diff --git a/ryu/services/protocols/bgp/rtconf/common.py b/ryu/services/protocols/bgp/rtconf/common.py index b4fc5ca9..05d3a7ac 100644 --- a/ryu/services/protocols/bgp/rtconf/common.py +++ b/ryu/services/protocols/bgp/rtconf/common.py @@ -229,9 +229,9 @@ class CommonConf(BaseConf): MAX_PATH_EXT_RTFILTER_ALL, DEFAULT_MAX_PATH_EXT_RTFILTER_ALL, **kwargs) - #========================================================================== + # ========================================================================= # Required attributes - #========================================================================== + # ========================================================================= @property def local_as(self): @@ -241,9 +241,9 @@ class CommonConf(BaseConf): def router_id(self): return self._settings[ROUTER_ID] - #========================================================================== + # ========================================================================= # Optional attributes with valid defaults. - #========================================================================== + # ========================================================================= @property def bgp_conn_retry_time(self): diff --git a/ryu/services/protocols/bgp/rtconf/neighbors.py b/ryu/services/protocols/bgp/rtconf/neighbors.py index c65af61c..ab7fa482 100644 --- a/ryu/services/protocols/bgp/rtconf/neighbors.py +++ b/ryu/services/protocols/bgp/rtconf/neighbors.py @@ -19,6 +19,18 @@ from abc import abstractmethod import logging +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_RTC_UC +from ryu.lib.packet.bgp import BGPOptParamCapabilityEnhancedRouteRefresh +from ryu.lib.packet.bgp import BGPOptParamCapabilityMultiprotocol +from ryu.lib.packet.bgp import BGPOptParamCapabilityRouteRefresh +from ryu.lib.packet.bgp import BGP_CAP_ENHANCED_ROUTE_REFRESH +from ryu.lib.packet.bgp import BGP_CAP_MULTIPROTOCOL +from ryu.lib.packet.bgp import BGP_CAP_ROUTE_REFRESH + from ryu.services.protocols.bgp.base import OrderedDict from ryu.services.protocols.bgp.rtconf.base import ADVERTISE_PEER_AS from ryu.services.protocols.bgp.rtconf.base import BaseConf @@ -45,17 +57,6 @@ from ryu.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS from ryu.services.protocols.bgp.rtconf.base import validate from ryu.services.protocols.bgp.rtconf.base import validate_med from ryu.services.protocols.bgp.rtconf.base import validate_soo_list - -from ryu.services.protocols.bgp.protocols.bgp.capabilities import \ - EnhancedRouteRefreshCap -from ryu.services.protocols.bgp.protocols.bgp.capabilities import \ - MultiprotocolExtentionCap -from ryu.services.protocols.bgp.protocols.bgp.capabilities import \ - RouteRefreshCap -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_VPN -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_VPN -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_RTC_UC from ryu.services.protocols.bgp.utils.validation import is_valid_ipv4 from ryu.services.protocols.bgp.utils.validation import is_valid_old_asn @@ -224,9 +225,9 @@ class NeighborConf(ConfWithId, ConfWithStats): self_valid_evts.update(NeighborConf.VALID_EVT) return self_valid_evts - #========================================================================== + # ========================================================================= # Required attributes - #========================================================================== + # ========================================================================= @property def remote_as(self): @@ -244,9 +245,9 @@ class NeighborConf(ConfWithId, ConfWithStats): def host_bind_port(self): return self._settings[LOCAL_PORT] - #========================================================================== + # ========================================================================= # Optional attributes with valid defaults. - #========================================================================== + # ========================================================================= @property def hold_time(self): @@ -288,9 +289,9 @@ class NeighborConf(ConfWithId, ConfWithStats): self._notify_listeners(NeighborConf.UPDATE_ENABLED_EVT, enable) - #========================================================================== + # ========================================================================= # Optional attributes with no valid defaults. - #========================================================================== + # ========================================================================= @property def multi_exit_disc(self): @@ -334,27 +335,35 @@ class NeighborConf(ConfWithId, ConfWithStats): capabilities = OrderedDict() mbgp_caps = [] if self.cap_mbgp_ipv4: - mbgp_caps.append(MultiprotocolExtentionCap(RF_IPv4_UC)) + mbgp_caps.append( + BGPOptParamCapabilityMultiprotocol( + RF_IPv4_UC.afi, RF_IPv4_UC.safi)) if self.cap_mbgp_vpnv4: - mbgp_caps.append(MultiprotocolExtentionCap(RF_IPv4_VPN)) + mbgp_caps.append( + BGPOptParamCapabilityMultiprotocol( + RF_IPv4_VPN.afi, RF_IPv4_VPN.safi)) if self.cap_mbgp_vpnv6: - mbgp_caps.append(MultiprotocolExtentionCap(RF_IPv6_VPN)) + mbgp_caps.append( + BGPOptParamCapabilityMultiprotocol( + RF_IPv6_VPN.afi, RF_IPv6_VPN.safi)) if self.cap_rtc: - mbgp_caps.append(MultiprotocolExtentionCap(RF_RTC_UC)) + mbgp_caps.append( + BGPOptParamCapabilityMultiprotocol( + RF_RTC_UC.afi, RF_RTC_UC.safi)) if mbgp_caps: - capabilities[MultiprotocolExtentionCap.CODE] = mbgp_caps + capabilities[BGP_CAP_MULTIPROTOCOL] = mbgp_caps if self.cap_refresh: - capabilities[RouteRefreshCap.CODE] = [ - RouteRefreshCap.get_singleton()] + capabilities[BGP_CAP_ROUTE_REFRESH] = [ + BGPOptParamCapabilityRouteRefresh()] if self.cap_enhanced_refresh: - capabilities[EnhancedRouteRefreshCap.CODE] = [ - EnhancedRouteRefreshCap.get_singleton()] + capabilities[BGP_CAP_ENHANCED_ROUTE_REFRESH] = [ + BGPOptParamCapabilityEnhancedRouteRefresh()] return capabilities diff --git a/ryu/services/protocols/bgp/rtconf/vrfs.py b/ryu/services/protocols/bgp/rtconf/vrfs.py index 6b7b60c4..48b4809f 100644 --- a/ryu/services/protocols/bgp/rtconf/vrfs.py +++ b/ryu/services/protocols/bgp/rtconf/vrfs.py @@ -20,9 +20,11 @@ import abc import logging -from ryu.services.protocols.bgp.protocols.bgp.pathattr import ExtCommunity -from ryu.services.protocols.bgp.utils import validation +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv6_UC +from ryu.lib.packet.bgp import BGPPathAttributeExtendedCommunities +from ryu.services.protocols.bgp.utils import validation from ryu.services.protocols.bgp.base import get_validator from ryu.services.protocols.bgp.rtconf.base import BaseConf from ryu.services.protocols.bgp.rtconf.base import BaseConfListener @@ -40,8 +42,6 @@ from ryu.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS from ryu.services.protocols.bgp.rtconf.base import validate from ryu.services.protocols.bgp.rtconf.base import validate_med from ryu.services.protocols.bgp.rtconf.base import validate_soo_list -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_UC LOG = logging.getLogger('bgpspeaker.rtconf.vrfs') @@ -73,11 +73,8 @@ def validate_import_rts(import_rts): if not (len(import_rts) <= MAX_NUM_IMPORT_RT): raise ConfigValueError(desc='Max. import RT is limited to %s' % MAX_NUM_IMPORT_RT) - try: - ExtCommunity.validate_supported_attributes(import_rts) - except ValueError: - raise ConfigValueError(conf_name=IMPORT_RTS, - conf_value=import_rts) + if not all(validation.is_valid_ext_comm_attr(rt) for rt in import_rts): + raise ConfigValueError(conf_name=IMPORT_RTS, conf_value=import_rts) # Check if we have duplicates unique_rts = set(import_rts) if len(unique_rts) != len(import_rts): @@ -94,9 +91,8 @@ def validate_export_rts(export_rts): if not (len(export_rts) <= MAX_NUM_EXPORT_RT): raise ConfigValueError(desc='Max. import RT is limited to %s' % MAX_NUM_EXPORT_RT) - try: - ExtCommunity.validate_supported_attributes(export_rts) - except Exception: + + if not all(validation.is_valid_ext_comm_attr(rt) for rt in export_rts): raise ConfigValueError(conf_name=EXPORT_RTS, conf_value=export_rts) # Check if we have duplicates unique_rts = set(export_rts) @@ -169,17 +165,17 @@ class VrfConf(ConfWithId, ConfWithStats): import_maps = kwargs.pop(IMPORT_MAPS, []) self._settings[IMPORT_MAPS] = import_maps - #========================================================================== + # ========================================================================= # Required attributes - #========================================================================== + # ========================================================================= @property def route_dist(self): return self._settings[ROUTE_DISTINGUISHER] - #========================================================================== + # ========================================================================= # Optional attributes with valid defaults. - #========================================================================== + # ========================================================================= @property def import_rts(self): diff --git a/ryu/services/protocols/bgp/speaker.py b/ryu/services/protocols/bgp/speaker.py index 67440442..af8f991a 100644 --- a/ryu/services/protocols/bgp/speaker.py +++ b/ryu/services/protocols/bgp/speaker.py @@ -21,6 +21,24 @@ import socket import struct import traceback +from ryu.lib.packet import bgp +from ryu.lib.packet.bgp import RouteFamily +from ryu.lib.packet.bgp import RF_RTC_UC +from ryu.lib.packet.bgp import BGPMessage +from ryu.lib.packet.bgp import BGPOpen +from ryu.lib.packet.bgp import BGPUpdate +from ryu.lib.packet.bgp import BGPKeepAlive +from ryu.lib.packet.bgp import BGPNotification +from ryu.lib.packet.bgp import BGPRouteRefresh +from ryu.lib.packet.bgp import BGP_MSG_OPEN +from ryu.lib.packet.bgp import BGP_MSG_UPDATE +from ryu.lib.packet.bgp import BGP_MSG_KEEPALIVE +from ryu.lib.packet.bgp import BGP_MSG_NOTIFICATION +from ryu.lib.packet.bgp import BGP_MSG_ROUTE_REFRESH +from ryu.lib.packet.bgp import BGP_CAP_ENHANCED_ROUTE_REFRESH +from ryu.lib.packet.bgp import BGP_CAP_MULTIPROTOCOL +from ryu.lib.packet.bgp import BGP_CAP_ROUTE_REFRESH + from ryu.services.protocols.bgp.base import Activity from ryu.services.protocols.bgp.base import add_bgp_error_metadata from ryu.services.protocols.bgp.base import BGPSException @@ -30,25 +48,8 @@ from ryu.services.protocols.bgp.constants import BGP_FSM_OPEN_CONFIRM from ryu.services.protocols.bgp.constants import BGP_FSM_OPEN_SENT from ryu.services.protocols.bgp.constants import BGP_VERSION_NUM from ryu.services.protocols.bgp.protocol import Protocol -from ryu.services.protocols.bgp.protocols.bgp.capabilities import \ - EnhancedRouteRefreshCap -from ryu.services.protocols.bgp.protocols.bgp.capabilities import \ - MultiprotocolExtentionCap -from ryu.services.protocols.bgp.protocols.bgp.capabilities import \ - RouteRefreshCap -import ryu.services.protocols.bgp.protocols.bgp.exceptions as exceptions -from ryu.services.protocols.bgp.protocols.bgp.exceptions import BgpExc -from ryu.services.protocols.bgp.protocols.bgp import messages -from ryu.services.protocols.bgp.protocols.bgp.messages import Keepalive -from ryu.services.protocols.bgp.protocols.bgp.messages import Notification -from ryu.services.protocols.bgp.protocols.bgp.messages import Open -from ryu.services.protocols.bgp.protocols.bgp.messages import RouteRefresh -from ryu.services.protocols.bgp.protocols.bgp.messages import Update -from ryu.services.protocols.bgp.protocols.bgp import nlri -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_RTC_UC from ryu.services.protocols.bgp.utils.validation import is_valid_old_asn - LOG = logging.getLogger('bgpspeaker.speaker') # BGP min. and max. message lengths as per RFC. @@ -56,7 +57,7 @@ BGP_MIN_MSG_LEN = 19 BGP_MAX_MSG_LEN = 4096 # Keep-alive singleton. -_KEEP_ALIVE = Keepalive() +_KEEP_ALIVE = BGPKeepAlive() @add_bgp_error_metadata(code=CORE_ERROR_CODE, sub_code=2, @@ -74,11 +75,11 @@ def nofitication_factory(code, subcode): - `code`: (int) BGP error code - `subcode`: (int) BGP error sub-code """ - reason = Notification.REASONS.get((code, subcode)) - if not reason: + notification = BGPNotification(code, subcode) + if not notification.reason: raise ValueError('Invalid code/sub-code.') - return Notification(code, subcode) + return notification class BgpProtocol(Protocol, Activity): @@ -174,8 +175,8 @@ class BgpProtocol(Protocol, Activity): peer_cap = self.recv_open_msg.caps # Both local and peer should advertise ERR capability for it to be # enabled. - if (local_cap.get(EnhancedRouteRefreshCap.CODE) and - peer_cap.get(EnhancedRouteRefreshCap.CODE)): + if (local_cap.get(BGP_CAP_ENHANCED_ROUTE_REFRESH) and + peer_cap.get(BGP_CAP_ENHANCED_ROUTE_REFRESH)): err_cap_enabled = True return err_cap_enabled @@ -183,14 +184,13 @@ class BgpProtocol(Protocol, Activity): def _check_route_fmly_adv(self, open_msg, route_family): match_found = False - local_caps = open_msg.caps - mbgp_cap = local_caps.get(MultiprotocolExtentionCap.CODE) - # Check MP_BGP capability was advertised. - if mbgp_cap: - # Iterate over all advertised mp_bgp caps to find a match. - for peer_cap in mbgp_cap: - if (route_family.afi == peer_cap.route_family.afi and - route_family.safi == peer_cap.route_family.safi): + local_caps = open_msg.opt_param + for cap in local_caps: + # Check MP_BGP capability was advertised. + if cap.cap_code == BGP_CAP_MULTIPROTOCOL: + # Iterate over all advertised mp_bgp caps to find a match. + if (route_family.afi == cap.afi and + route_family.safi == cap.safi): match_found = True return match_found @@ -218,8 +218,8 @@ class BgpProtocol(Protocol, Activity): local_caps = self.sent_open_msg.caps remote_caps = self.recv_open_msg.caps - local_mbgp_cap = local_caps.get(MultiprotocolExtentionCap.CODE) - remote_mbgp_cap = remote_caps.get(MultiprotocolExtentionCap.CODE) + local_mbgp_cap = local_caps.get(BGP_CAP_MULTIPROTOCOL) + remote_mbgp_cap = remote_caps.get(BGP_CAP_MULTIPROTOCOL) # Check MP_BGP capabilities were advertised. if local_mbgp_cap and remote_mbgp_cap: local_families = { @@ -236,7 +236,7 @@ class BgpProtocol(Protocol, Activity): afs = [] for afi, safi in afi_safi: - afs.append(nlri.get_rf(afi, safi)) + afs.append(RouteFamily(afi, safi)) return afs def is_mbgp_cap_valid(self, route_family): @@ -262,7 +262,7 @@ class BgpProtocol(Protocol, Activity): def data_received(self, next_bytes): try: self._data_received(next_bytes) - except BgpExc as exc: + except bgp.BgpExc as exc: LOG.error( "BGPExc Exception while receiving data: " "%s \n Traceback %s \n" @@ -310,7 +310,7 @@ class BgpProtocol(Protocol, Activity): # authentication. if (auth != BgpProtocol.MESSAGE_MARKER): LOG.error('Invalid message marker received: %s' % auth) - raise exceptions.NotSync() + raise bgp.NotSync() # Check if we have valid bgp message length. check = lambda: length < BGP_MIN_MSG_LEN\ @@ -318,36 +318,27 @@ class BgpProtocol(Protocol, Activity): # RFC says: The minimum length of the OPEN message is 29 # octets (including the message header). - check2 = lambda: ptype == Open.TYPE_CODE\ - and length < Open.MIN_LENGTH + check2 = lambda: ptype == BGP_MSG_OPEN\ + and length < BGPOpen._MIN_LEN # RFC says: A KEEPALIVE message consists of only the # message header and has a length of 19 octets. - check3 = lambda: ptype == Keepalive.TYPE_CODE\ - and length != BGP_MIN_MSG_LEN + check3 = lambda: ptype == BGP_MSG_KEEPALIVE\ + and length != BGPKeepAlive._MIN_LEN # RFC says: The minimum length of the UPDATE message is 23 # octets. - check4 = lambda: ptype == Update.TYPE_CODE\ - and length < Update.MIN_LENGTH + check4 = lambda: ptype == BGP_MSG_UPDATE\ + and length < BGPUpdate._MIN_LEN if check() or check2() or check3() or check4(): - raise exceptions.BadLen(ptype, length) + raise bgp.BadLen(ptype, length) # If we have partial message we wait for rest of the message. if len(self._recv_buff) < length: return - - # If we have full message, we get its payload/data. - payload = self._recv_buff[BGP_MIN_MSG_LEN:length] - - # Update buffer to not contain any part of the current message. - self._recv_buff = self._recv_buff[length:] - - # Try to decode payload into specified message type. - # If we have any error parsing the message, we send appropriate - # bgp notification message. - msg = messages.decode(ptype, payload, length) + msg, rest = BGPMessage.parser(self._recv_buff) + self._recv_buff = rest # If we have a valid bgp message we call message handler. self._handle_msg(msg) @@ -365,14 +356,9 @@ class BgpProtocol(Protocol, Activity): RFC ref: http://tools.ietf.org/html/rfc4486 http://www.iana.org/assignments/bgp-parameters/bgp-parameters.xhtml """ - reason = Notification.REASONS.get((code, subcode)) - if not reason: - # Not checking for type of parameters to allow some flexibility - # via. duck-typing. - raise ValueError('Unsupported code/sub-code given.') - - notification = Notification(code, subcode, reason) - self._socket.sendall(notification.encode()) + notification = BGPNotification(code, subcode) + reason = notification.reason + self._socket.sendall(notification.serialize()) self._signal_bus.bgp_error(self._peer, code, subcode, reason) LOG.error( 'Sent notification to %r>> %s' % @@ -385,8 +371,8 @@ class BgpProtocol(Protocol, Activity): raise BgpProtocolException('Tried to send message to peer when ' 'this protocol instance is not started' ' or is no longer is started state.') - self._socket.sendall(msg.encode()) - if msg.MSG_NAME == Notification.MSG_NAME: + self._socket.sendall(msg.serialize()) + if msg.type == BGP_MSG_NOTIFICATION: LOG.error('Sent notification to %s>> %s' % (self.get_peername(), msg)) @@ -394,7 +380,7 @@ class BgpProtocol(Protocol, Activity): else: LOG.debug('Sent msg. %s to %s>> %s' % - (msg.MSG_NAME, self.get_peername(), msg)) + (msg.__class__, self.get_peername(), msg)) def stop(self): Activity.stop(self) @@ -407,28 +393,31 @@ class BgpProtocol(Protocol, Activity): settings. RTC or RR/ERR are MUST capability if peer does not support either one of them we have to end session. """ - assert open_msg.TYPE_CODE == Open.TYPE_CODE + assert open_msg.type == BGP_MSG_OPEN # Validate remote ASN. - remote_asnum = open_msg.asnum + remote_asnum = open_msg.my_as # Since 4byte AS is not yet supported, we validate AS as old style AS. if (not is_valid_old_asn(remote_asnum) or remote_asnum != self._peer.remote_as): - raise exceptions.BadPeerAs() + raise bgp.BadPeerAs() # Validate bgp version number. if open_msg.version != BGP_VERSION_NUM: - raise exceptions.UnsupportedVersion(BGP_VERSION_NUM) - - adv_caps = open_msg.caps - rr_cap_adv = adv_caps.get(RouteRefreshCap.CODE) - err_cap_adv = adv_caps.get(EnhancedRouteRefreshCap.CODE) + raise bgp.UnsupportedVersion(BGP_VERSION_NUM) + + adv_caps = open_msg.opt_param + for cap in adv_caps: + if cap.cap_code == BGP_CAP_ROUTE_REFRESH: + rr_cap_adv = cap + elif cap.cap_code == BGP_CAP_ENHANCED_ROUTE_REFRESH: + err_cap_adv = cap # If either RTC or RR/ERR are MUST capability if peer does not support # either one of them we have to end session as we have to request peer # to send prefixes for new VPNs that may be created automatically. # TODO(PH): Check with experts if error is suitable in this case if not (rr_cap_adv or err_cap_adv or self._check_route_fmly_adv(open_msg, RF_RTC_UC)): - raise exceptions.UnsupportedOptParam() + raise bgp.UnsupportedOptParam() def _handle_msg(self, msg): """When a BGP message is received, send it to peer. @@ -438,10 +427,10 @@ class BgpProtocol(Protocol, Activity): *Notification* message we close connection with peer. """ LOG.debug('Received %s msg. from %s<< \n%s' % - (msg.MSG_NAME, str(self.get_peername()), msg)) + (msg.__class__, str(self.get_peername()), msg)) # If we receive open message we try to bind to protocol - if (msg.MSG_NAME == Open.MSG_NAME): + if (msg.type == BGP_MSG_OPEN): if self.state == BGP_FSM_OPEN_SENT: # Validate open message. self._validate_open_msg(msg) @@ -458,18 +447,18 @@ class BgpProtocol(Protocol, Activity): # resolution choose different instance of protocol and this # instance has to close. Before closing it sends # appropriate notification msg. to peer. - raise exceptions.CollisionResolution() + raise bgp.CollisionResolution() # If peer sends Hold Time as zero, then according to RFC we do # not set Hold Time and Keep Alive timer. - if msg.holdtime == 0: + if msg.hold_time == 0: LOG.info('The Hold Time sent by the peer is zero, hence ' 'not setting any Hold Time and Keep Alive' ' timers.') else: # Start Keep Alive timer considering Hold Time preference # of the peer. - self._start_timers(msg.holdtime) + self._start_timers(msg.hold_time) self._send_keepalive() # Peer does not see open message. @@ -480,8 +469,8 @@ class BgpProtocol(Protocol, Activity): 'OpenSent') # Received out-of-order open message # We raise Finite state machine error - raise exceptions.FiniteStateMachineError() - elif msg.MSG_NAME == Notification.MSG_NAME: + raise bgp.FiniteStateMachineError() + elif msg.type == BGP_MSG_NOTIFICATION: if self._peer: self._signal_bus.bgp_notification_received(self._peer, msg) # If we receive notification message @@ -491,14 +480,14 @@ class BgpProtocol(Protocol, Activity): return # If we receive keepalive or update message, we reset expire timer. - if (msg.MSG_NAME == Keepalive.MSG_NAME or - msg.MSG_NAME == Update.MSG_NAME): + if (msg.type == BGP_MSG_KEEPALIVE or + msg.type == BGP_MSG_UPDATE): if self._expiry: self._expiry.reset() # Call peer message handler for appropriate messages. - if (msg.MSG_NAME in - (Keepalive.MSG_NAME, Update.MSG_NAME, RouteRefresh.MSG_NAME)): + if (msg.type in + (BGP_MSG_UPDATE, BGP_MSG_KEEPALIVE, BGP_MSG_ROUTE_REFRESH)): self._peer.handle_msg(msg) # We give chance to other threads to run. self.pause(0) @@ -529,8 +518,8 @@ class BgpProtocol(Protocol, Activity): """Hold timer expired event handler. """ LOG.info('Negotiated hold time %s expired.' % self._holdtime) - code = exceptions.HoldTimerExpired.CODE - subcode = exceptions.HoldTimerExpired.SUB_CODE + code = BGP_ERROR_HOLD_TIMER_EXPIRED + subcode = BGP_ERROR_SUB_HOLD_TIMER_EXPIRED self.send_notification(code, subcode) self.connection_lost('Negotiated hold time %s expired.' % self._holdtime) @@ -554,7 +543,7 @@ class BgpProtocol(Protocol, Activity): self.data_received(next_bytes) except socket.error as err: conn_lost_reason = 'Connection to peer lost: %s.' % err - except BgpExc as ex: + except bgp.BgpExc as ex: conn_lost_reason = 'Connection to peer lost, reason: %s.' % ex except Exception as e: LOG.debug(traceback.format_exc()) @@ -570,7 +559,7 @@ class BgpProtocol(Protocol, Activity): assert self.state == BGP_FSM_CONNECT # We have a connection with peer we send open message. open_msg = self._peer.create_open_msg() - self._holdtime = open_msg.holdtime + self._holdtime = open_msg.hold_time self.state = BGP_FSM_OPEN_SENT if not self.is_reactive: self._peer.state.bgp_state = self.state diff --git a/ryu/services/protocols/bgp/utils/bgp.py b/ryu/services/protocols/bgp/utils/bgp.py index fe22c45b..4e7391be 100644 --- a/ryu/services/protocols/bgp/utils/bgp.py +++ b/ryu/services/protocols/bgp/utils/bgp.py @@ -19,14 +19,16 @@ import logging import socket -from ryu.services.protocols.bgp.protocols.bgp.messages import Update -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv4_VPN -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_IPv6_VPN -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_RTC_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RtNlri -from ryu.services.protocols.bgp.protocols.bgp import pathattr -from ryu.services.protocols.bgp.protocols.bgp.pathattr import Med +from ryu.lib.packet.bgp import BGPUpdate +from ryu.lib.packet.bgp import RF_IPv4_UC +from ryu.lib.packet.bgp import RF_IPv4_VPN +from ryu.lib.packet.bgp import RF_IPv6_VPN +from ryu.lib.packet.bgp import RF_RTC_UC +from ryu.lib.packet.bgp import RouteTargetMembershipNLRI +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_MULTI_EXIT_DISC +from ryu.lib.packet.bgp import BGPPathAttributeMultiExitDisc +from ryu.lib.packet.bgp import BGPPathAttributeMpUnreachNLRI +from ryu.lib.packet.bgp import BGPPathAttributeUnknown from ryu.services.protocols.bgp.info_base.rtc import RtcPath from ryu.services.protocols.bgp.info_base.ipv4 import Ipv4Path from ryu.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path @@ -43,7 +45,7 @@ _ROUTE_FAMILY_TO_PATH_MAP = {RF_IPv4_UC: Ipv4Path, def create_path(src_peer, nlri, **kwargs): - route_family = nlri.route_family + route_family = nlri.ROUTE_FAMILY assert route_family in _ROUTE_FAMILY_TO_PATH_MAP.keys() path_cls = _ROUTE_FAMILY_TO_PATH_MAP.get(route_family) return path_cls(src_peer, nlri, src_peer.version_num, **kwargs) @@ -57,7 +59,7 @@ def clone_path_and_update_med_for_target_neighbor(path, med): route_family) path_cls = _ROUTE_FAMILY_TO_PATH_MAP.get(route_family) pattrs = path.pathattr_map - pattrs[Med.ATTR_NAME] = Med(med) + pattrs[BGP_ATTR_TYPE_MULTI_EXIT_DISC] = BGPPathAttributeMultiExitDisc(med) return path_cls( path.source, path.nlri, path.source_version_num, pattrs=pattrs, nexthop=path.nexthop, @@ -77,7 +79,7 @@ def clone_rtcpath_update_rt_as(path, new_rt_as): if not path or path.route_family != RF_RTC_UC: raise ValueError('Expected RT_NLRI path') old_nlri = path.nlri - new_rt_nlri = RtNlri(new_rt_as, old_nlri.route_target) + new_rt_nlri = RouteTargetMembershipNLRI(new_rt_as, old_nlri.route_target) return RtcPath(path.source, new_rt_nlri, path.source_version_num, pattrs=path.pathattr_map, nexthop=path.nexthop, is_withdraw=path.is_withdraw) @@ -106,7 +108,7 @@ def get_unknow_opttrans_attr(path): path_attrs = path.pathattr_map unknown_opt_tran_attrs = {} for _, attr in path_attrs.iteritems(): - if (isinstance(attr, pathattr.UnRcgPathAttr) and + if (isinstance(attr, BGPPathAttributeUnknown) and attr.is_optional_transitive()): unknown_opt_tran_attrs[attr.type_code] = attr return unknown_opt_tran_attrs @@ -114,9 +116,10 @@ def get_unknow_opttrans_attr(path): def create_end_of_rib_update(): """Construct end-of-rib (EOR) Update instance.""" - mpunreach_attr = pathattr.MpUnreachNlri(RF_IPv4_VPN, []) - pathattr_map = {pathattr.MpUnreachNlri.ATTR_NAME: mpunreach_attr} - eor = Update(pathattr_map) + mpunreach_attr = BGPPathAttributeMpUnreachNLRI(RF_IPv4_VPN.afi, + RF_IPv4_VPN.safi, + []) + eor = BGPUpdate(path_attributes=[mpunreach_attr]) return eor diff --git a/ryu/services/protocols/bgp/utils/rtfilter.py b/ryu/services/protocols/bgp/utils/rtfilter.py index cfc9f899..aa8d42a9 100644 --- a/ryu/services/protocols/bgp/utils/rtfilter.py +++ b/ryu/services/protocols/bgp/utils/rtfilter.py @@ -18,10 +18,12 @@ """ import logging -from ryu.services.protocols.bgp.protocols.bgp.nlri import RF_RTC_UC -from ryu.services.protocols.bgp.protocols.bgp.nlri import RtNlri -from ryu.services.protocols.bgp.protocols.bgp.pathattr import AsPath -from ryu.services.protocols.bgp.protocols.bgp.pathattr import Origin +from ryu.lib.packet.bgp import RF_RTC_UC +from ryu.lib.packet.bgp import RouteTargetMembershipNLRI +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_AS_PATH +from ryu.lib.packet.bgp import BGP_ATTR_TYPE_ORIGIN +from ryu.lib.packet.bgp import BGPPathAttributeAsPath +from ryu.lib.packet.bgp import BGPPathAttributeOrigin from ryu.services.protocols.bgp.base import OrderedDict from ryu.services.protocols.bgp.info_base.rtc import RtcPath @@ -75,14 +77,15 @@ class RouteTargetManager(object): def _add_rt_nlri_for_as(self, rtc_as, route_target, is_withdraw=False): from ryu.services.protocols.bgp.core import EXPECTED_ORIGIN - rt_nlri = RtNlri(rtc_as, route_target) + rt_nlri = RouteTargetMembershipNLRI(rtc_as, route_target) # Create a dictionary for path-attrs. pattrs = OrderedDict() if not is_withdraw: # MpReachNlri and/or MpUnReachNlri attribute info. is contained # in the path. Hence we do not add these attributes here. - pattrs[Origin.ATTR_NAME] = Origin(EXPECTED_ORIGIN) - pattrs[AsPath.ATTR_NAME] = AsPath([]) + pattrs[BGP_ATTR_TYPE_ORIGIN] = BGPPathAttributeOrigin( + EXPECTED_ORIGIN) + pattrs[BGP_ATTR_TYPE_AS_PATH] = BGPPathAttributeAsPath([]) # Create Path instance and initialize appropriately. path = RtcPath(None, rt_nlri, 0, is_withdraw=is_withdraw, @@ -152,7 +155,7 @@ class RouteTargetManager(object): else: # New RT could be Default RT, which means we need to share this # path - desired_rts.add(RtNlri.DEFAULT_RT) + desired_rts.add(RouteTargetMembershipNLRI.DEFAULT_RT) # If we have RT filter has new RTs that are common with path # RTs, then we send this path to peer if desired_rts.intersection(new_rts): @@ -172,8 +175,8 @@ class RouteTargetManager(object): interested_rts.update(self._vrfs_conf.vrf_interested_rts) # Remove default RT as it is not a valid RT for paths # TODO(PH): Check if we have better alternative than add and remove - interested_rts.add(RtNlri.DEFAULT_RT) - interested_rts.remove(RtNlri.DEFAULT_RT) + interested_rts.add(RouteTargetMembershipNLRI.DEFAULT_RT) + interested_rts.remove(RouteTargetMembershipNLRI.DEFAULT_RT) return interested_rts def update_interested_rts(self): |