move filter class from bgpspeaker.py to info_base/base.py to fix the error shown below.
$ sudo env PYTHONPATH=/home/wataru/ryu ~/ryu/bin/ryu run --config-file=~/etc/ryu01.conf ./application.py loading app ./application.py instantiating app ./application.py of RyuBGPSpeaker INFO 2014-07-21 06:14:48,066 base 207 API method core.start called with args: {'router_id': '10.10.0.1', 'label_range': (100, 100000), 'waiter': <ryu.lib.hub.Event object at 0x1a15dd0>, 'local_as': 64512, 'bgp_server_port': 179, 'refresh_max_eor_time': 0, 'refresh_stalepath_time': 0} Traceback (most recent call last): File "/home/wataru/ryu/bin/ryu", line 20, in <module> main() File "/home/wataru/ryu/ryu/cmd/ryu_base.py", line 75, in main subcmd.run(base_conf.subcommand_args) File "/home/wataru/ryu/ryu/cmd/ryu_base.py", line 58, in run self.entry(args=args, prog=prog) File "/home/wataru/ryu/ryu/cmd/manager.py", line 81, in main services.extend(app_mgr.instantiate_apps(**contexts)) File "/home/wataru/ryu/ryu/base/app_manager.py", line 486, in instantiate_apps t = app.start() File "/home/wataru/ryu/ryu/services/protocols/bgp/application.py", line 93, in start self._start_core(settings) File "/home/wataru/ryu/ryu/services/protocols/bgp/application.py", line 168, in _start_core call('core.start', waiter=waiter, **common_settings) File "/home/wataru/ryu/ryu/services/protocols/bgp/api/base.py", line 210, in call import all # noqa File "/home/wataru/ryu/ryu/services/protocols/bgp/api/all.py", line 4, in <module> import prefix File "/home/wataru/ryu/ryu/services/protocols/bgp/api/prefix.py", line 29, in <module> from ryu.services.protocols.bgp.core import BgpCoreError File "/home/wataru/ryu/ryu/services/protocols/bgp/core.py", line 37, in <module> from ryu.services.protocols.bgp import core_managers File "/home/wataru/ryu/ryu/services/protocols/bgp/core_managers/__init__.py", line 19, in <module> from peer_manager import PeerManager File "/home/wataru/ryu/ryu/services/protocols/bgp/core_managers/peer_manager.py", line 6, in <module> from ryu.services.protocols.bgp.peer import Peer File "/home/wataru/ryu/ryu/services/protocols/bgp/peer.py", line 32, in <module> from ryu.services.protocols.bgp.bgpspeaker import PrefixList File "/home/wataru/ryu/ryu/services/protocols/bgp/bgpspeaker.py", line 56, in <module> from ryu.services.protocols.bgp.application import RyuBGPSpeaker File "/home/wataru/ryu/ryu/services/protocols/bgp/application.py", line 64, in <module> def_desc='Unknown bootstrap exception.') File "/home/wataru/ryu/ryu/services/protocols/bgp/base.py", line 105, in add_bgp_error_metadata 'already defined.' % (code, sub_code)) ValueError: BGPSException with code 300 and sub-code 1 already defined. Signed-off-by: ISHIDA Wataru <ishida.wat...@lab.ntt.co.jp> --- ryu/services/protocols/bgp/bgpspeaker.py | 126 --------------------- ryu/services/protocols/bgp/info_base/base.py | 152 ++++++++++++++++++++++++++ ryu/services/protocols/bgp/peer.py | 14 +-- 3 files changed, 159 insertions(+), 133 deletions(-) diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py index b4a273c..c482fd5 100644 --- a/ryu/services/protocols/bgp/bgpspeaker.py +++ b/ryu/services/protocols/bgp/bgpspeaker.py @@ -54,7 +54,6 @@ from ryu.services.protocols.bgp.rtconf.neighbors import PEER_NEXT_HOP from ryu.services.protocols.bgp.rtconf.neighbors import PASSWORD from ryu.services.protocols.bgp.rtconf.neighbors import OUT_FILTER from ryu.services.protocols.bgp.application import RyuBGPSpeaker -from netaddr.ip import IPAddress, IPNetwork from ryu.lib.packet.bgp import RF_IPv4_UC, RF_IPv6_UC @@ -87,131 +86,6 @@ class EventPrefix(object): self.is_withdraw = is_withdraw -class PrefixList(object): - """ - used to specify a prefix for out-filter. - - We can create PrefixList object as follows. - - prefix_list = PrefixList('10.5.111.0/24', policy=PrefixList.POLICY_PERMIT) - - ================ ================================================== - Attribute Description - ================ ================================================== - prefix A prefix used for out-filter - policy PrefixList.POLICY.PERMIT or PrefixList.POLICY_DENY - ge Prefix length that will be applied out-filter. - ge means greater than or equal. - le Prefix length that will be applied out-filter. - le means less than or equal. - ================ ================================================== - - - For example, when PrefixList object is created as follows: - - * p = PrefixList('10.5.111.0/24', - policy=PrefixList.POLICY_DENY, - ge=26, le=28) - - - prefixes which match 10.5.111.0/24 and its length matches - from 26 to 28 will be filtered and stopped to send to neighbor - because of POLICY_DENY. If you specify POLICY_PERMIT, - the path is sent to neighbor. - - If you don't want to send prefixes 10.5.111.64/26 and 10.5.111.32/27 - and 10.5.111.16/28, and allow to send other 10.5.111.0's prefixes, - you can do it by specifying as follows; - - * p = PrefixList('10.5.111.0/24', - policy=PrefixList.POLICY_DENY, - ge=26, le=28). - - """ - POLICY_DENY = 0 - POLICY_PERMIT = 1 - - def __init__(self, prefix, policy=POLICY_PERMIT, ge=None, le=None): - self._prefix = prefix - self._policy = policy - self._network = IPNetwork(prefix) - self._ge = ge - self._le = le - - def __cmp__(self, other): - return cmp(self.prefix, other.prefix) - - def __repr__(self): - policy = 'PERMIT' \ - if self._policy == self.POLICY_PERMIT else 'DENY' - - return 'PrefixList(prefix=%s,policy=%s,ge=%s,le=%s)'\ - % (self._prefix, policy, self._ge, self._le) - - @property - def prefix(self): - return self._prefix - - @property - def policy(self): - return self._policy - - @property - def ge(self): - return self._ge - - @property - def le(self): - return self._le - - def evaluate(self, prefix): - """ This method evaluates the prefix. - - Returns this object's policy and the result of matching. - If the specified prefix matches this object's prefix and - ge and le condition, - this method returns True as the matching result. - - ``prefix`` specifies the prefix. prefix must be string. - - """ - - result = False - length = prefix.length - net = IPNetwork(prefix.formatted_nlri_str) - - if net in self._network: - if self._ge is None and self._le is None: - result = True - - elif self._ge is None and self._le: - if length <= self._le: - result = True - - elif self._ge and self._le is None: - if self._ge <= length: - result = True - - elif self._ge and self._le: - if self._ge <= length <= self._le: - result = True - - return self.policy, result - - def clone(self): - """ This method clones PrefixList object. - - Returns PrefixList object that has the same values with the - original one. - - """ - - return PrefixList(self.prefix, - policy=self._policy, - ge=self._ge, - le=self._le) - - class BGPSpeaker(object): def __init__(self, as_number, router_id, bgp_server_port=DEFAULT_BGP_SERVER_PORT, diff --git a/ryu/services/protocols/bgp/info_base/base.py b/ryu/services/protocols/bgp/info_base/base.py index aaf3aa1..542448f 100644 --- a/ryu/services/protocols/bgp/info_base/base.py +++ b/ryu/services/protocols/bgp/info_base/base.py @@ -23,6 +23,7 @@ from abc import ABCMeta from abc import abstractmethod from copy import copy import logging +import netaddr from ryu.lib.packet.bgp import RF_IPv4_UC from ryu.lib.packet.bgp import RouteTargetMembershipNLRI @@ -806,3 +807,154 @@ class Path(object): return ('Path(%s, %s, %s, %s, %s, %s)' % ( self._source, self._nlri, self._source_version_num, self._path_attr_map, self._nexthop, self._is_withdraw)) + + +class Filter(object): + """Represents a general filter for in-bound and out-bound filter + + ================ ================================================== + Attribute Description + ================ ================================================== + policy Filter.POLICY_PERMIT or Filter.POLICY_DENY + ================ ================================================== + + """ + __metaclass__ = ABCMeta + + POLICY_DENY = 0 + POLICY_PERMIT = 1 + + def __init__(self, policy=POLICY_DENY): + self._policy = policy + + @property + def policy(self): + return self._policy + + @abstractmethod + def evaluate(self, path): + raise NotImplementedError() + + +class PrefixList(Filter): + """ + used to specify a prefix for out-filter. + + We can create PrefixList object as follows. + + prefix_list = PrefixList('10.5.111.0/24', policy=PrefixList.POLICY_PERMIT) + + ================ ================================================== + Attribute Description + ================ ================================================== + prefix A prefix used for out-filter + policy PrefixList.POLICY.PERMIT or PrefixList.POLICY_DENY + ge Prefix length that will be applied out-filter. + ge means greater than or equal. + le Prefix length that will be applied out-filter. + le means less than or equal. + ================ ================================================== + + + For example, when PrefixList object is created as follows: + + * p = PrefixList('10.5.111.0/24', + policy=PrefixList.POLICY_DENY, + ge=26, le=28) + + + prefixes which match 10.5.111.0/24 and its length matches + from 26 to 28 will be filtered and stopped to send to neighbor + because of POLICY_DENY. If you specify POLICY_PERMIT, + the path is sent to neighbor. + + If you don't want to send prefixes 10.5.111.64/26 and 10.5.111.32/27 + and 10.5.111.16/28, and allow to send other 10.5.111.0's prefixes, + you can do it by specifying as follows; + + * p = PrefixList('10.5.111.0/24', + policy=PrefixList.POLICY_DENY, + ge=26, le=28). + + """ + + def __init__(self, prefix, policy, ge=None, le=None): + super(PrefixList, self).__init__(policy) + self._prefix = prefix + self._network = netaddr.IPNetwork(prefix) + self._ge = ge + self._le = le + + def __cmp__(self, other): + return cmp(self.prefix, other.prefix) + + def __repr__(self): + policy = 'PERMIT' \ + if self._policy == self.POLICY_PERMIT else 'DENY' + + return 'PrefixList(prefix=%s,policy=%s,ge=%s,le=%s)'\ + % (self._prefix, policy, self._ge, self._le) + + @property + def prefix(self): + return self._prefix + + @property + def policy(self): + return self._policy + + @property + def ge(self): + return self._ge + + @property + def le(self): + return self._le + + def evaluate(self, path): + """ This method evaluates the prefix. + + Returns this object's policy and the result of matching. + If the specified prefix matches this object's prefix and + ge and le condition, + this method returns True as the matching result. + + ``prefix`` specifies the prefix. prefix must be string. + + """ + prefix = path.nlri + + result = False + length = prefix.length + net = netaddr.IPNetwork(prefix.formatted_nlri_str) + + if net in self._network: + if self._ge is None and self._le is None: + result = True + + elif self._ge is None and self._le: + if length <= self._le: + result = True + + elif self._ge and self._le is None: + if self._ge <= length: + result = True + + elif self._ge and self._le: + if self._ge <= length <= self._le: + result = True + + return self.policy, result + + def clone(self): + """ This method clones PrefixList object. + + Returns PrefixList object that has the same values with the + original one. + + """ + + return PrefixList(self.prefix, + policy=self._policy, + ge=self._ge, + le=self._le) diff --git a/ryu/services/protocols/bgp/peer.py b/ryu/services/protocols/bgp/peer.py index 4b3675a..95cfa6f 100644 --- a/ryu/services/protocols/bgp/peer.py +++ b/ryu/services/protocols/bgp/peer.py @@ -29,7 +29,7 @@ from ryu.services.protocols.bgp.base import SUPPORTED_GLOBAL_RF from ryu.services.protocols.bgp import constants as const from ryu.services.protocols.bgp.model import OutgoingRoute from ryu.services.protocols.bgp.model import SentRoute -from ryu.services.protocols.bgp.bgpspeaker import PrefixList +from ryu.services.protocols.bgp.info_base.base import PrefixList from ryu.services.protocols.bgp.net_ctrl import NET_CONTROLLER from ryu.services.protocols.bgp.rtconf.neighbors import NeighborConfListener from ryu.services.protocols.bgp.signals.emit import BgpSignalBus @@ -457,11 +457,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity): continue for sent_route in sent_routes: - nlri = sent_route.path.nlri - nlri_str = nlri.formatted_nlri_str + path = sent_route.path + nlri_str = path.nlri.formatted_nlri_str send_withdraw = False for pl in prefix_lists: - policy, result = pl.evaluate(nlri) + policy, result = pl.evaluate(path) if policy == PrefixList.POLICY_PERMIT and result: send_withdraw = False @@ -536,8 +536,8 @@ class Peer(Source, Sink, NeighborConfListener, Activity): if not outgoing_route.path.is_withdraw: for prefix_list in prefix_lists: - nlri = outgoing_route.path.nlri - policy, is_matched = prefix_list.evaluate(nlri) + path = outgoing_route.path + policy, is_matched = prefix_list.evaluate(path) if policy == PrefixList.POLICY_PERMIT and is_matched: allow_to_send = True break @@ -555,7 +555,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity): self.state.incr(PeerCounterNames.SENT_UPDATES) else: LOG.debug('prefix : %s is not sent by filter : %s' - % (nlri, blocked_cause)) + % (path.nlri, blocked_cause)) # We have to create sent_route for every OutgoingRoute which is # not a withdraw or was for route-refresh msg. -- 1.7.10.4 ------------------------------------------------------------------------------ Infragistics Professional Build stunning WinForms apps today! Reboot your WinForms applications with our WinForms controls. Build a bridge from your legacy apps to the future. http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk _______________________________________________ Ryu-devel mailing list Ryu-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/ryu-devel