bgp: fix bugs related to filter

previous implementation apply all filters to all paths regardless of
its route family. this implementation cause error like one shown below.

ryu.lib.hub l.60   |    ERROR | hub: uncaught exception:
Traceback (most recent call last):
  File "/home/wataru/ryu/ryu/lib/hub.py", line 52, in _launch
    func(*args, **kwargs)
  File "/home/wataru/ryu/ryu/services/protocols/bgp/peer.py", line 650,
in _process_outgoing_msg_list
    self._send_outgoing_route(outgoing_msg)
  File "/home/wataru/ryu/ryu/services/protocols/bgp/peer.py", line 599,
in _send_outgoing_route
    block, blocked_cause = self._apply_out_filter(path)
  File "/home/wataru/ryu/ryu/services/protocols/bgp/peer.py", line 505,
in _apply_out_filter
    return self._apply_filter(self._out_filters, path)
  File "/home/wataru/ryu/ryu/services/protocols/bgp/peer.py", line 490,
in _apply_filter
    policy, is_matched = filter_.evaluate(path)
  File "/home/wataru/ryu/ryu/services/protocols/bgp/info_base/base.py",
line 953, in evaluate
    net = netaddr.IPNetwork(prefix.formatted_nlri_str)
  File "/usr/local/lib/python2.7/dist-packages/netaddr/ip/__init__.py",
line 941, in __init__
    raise AddrFormatError('invalid IPNetwork %s' % addr)
AddrFormatError: invalid IPNetwork 100💯20.0.0.0/24

To fix this bug, this patch introduce the Ipv4PrefixFilter and Ipv6PrefixFilter
class which is only applied to the ipv4 path and ipv6 path.

other condition bug related to applying filter is also fixed.

Signed-off-by: ISHIDA Wataru <ishida.wataru@lab.ntt.co.jp>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
ISHIDA Wataru 2014-07-30 14:01:39 +09:00 committed by FUJITA Tomonori
parent 184c88b359
commit 3fa25edeae
4 changed files with 24 additions and 7 deletions

View File

@ -821,6 +821,8 @@ class Filter(object):
"""
__metaclass__ = ABCMeta
ROUTE_FAMILY = RF_IPv4_UC
POLICY_DENY = 0
POLICY_PERMIT = 1
@ -978,7 +980,7 @@ class PrefixFilter(Filter):
"""
return PrefixFilter(self.prefix,
policy=self._policy,
ge=self._ge,
le=self._le)
return self.__class__(self.prefix,
policy=self._policy,
ge=self._ge,
le=self._le)

View File

@ -25,6 +25,7 @@ from ryu.services.protocols.bgp.info_base.base import Path
from ryu.services.protocols.bgp.info_base.base import Table
from ryu.services.protocols.bgp.info_base.base import Destination
from ryu.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin
from ryu.services.protocols.bgp.info_base.base import PrefixFilter
LOG = logging.getLogger('bgpspeaker.info_base.ipv4')
@ -83,3 +84,8 @@ class Ipv4Path(Path):
super(Ipv4Path, self).__init__(*args, **kwargs)
from ryu.services.protocols.bgp.info_base.vrf4 import Vrf4Path
self.VRF_PATH_CLASS = Vrf4Path
class Ipv4PrefixFilter(PrefixFilter):
"""IPv4 Prefix Filter class"""
ROUTE_FAMILY = RF_IPv4_UC

View File

@ -25,6 +25,7 @@ from ryu.services.protocols.bgp.info_base.base import Path
from ryu.services.protocols.bgp.info_base.base import Table
from ryu.services.protocols.bgp.info_base.base import Destination
from ryu.services.protocols.bgp.info_base.base import NonVrfPathProcessingMixin
from ryu.services.protocols.bgp.info_base.base import PrefixFilter
LOG = logging.getLogger('bgpspeaker.info_base.ipv6')
@ -83,3 +84,8 @@ class Ipv6Path(Path):
super(Ipv6Path, self).__init__(*args, **kwargs)
from ryu.services.protocols.bgp.info_base.vrf6 import Vrf6Path
self.VRF_PATH_CLASS = Vrf6Path
class Ipv6PrefixFilter(PrefixFilter):
"""IPv6 Prefix Filter class"""
ROUTE_FAMILY = RF_IPv6_UC

View File

@ -487,6 +487,9 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
blocked_cause = None
for filter_ in filters:
if filter_.ROUTE_FAMILY != path.ROUTE_FAMILY:
continue
policy, is_matched = filter_.evaluate(path)
if policy == PrefixFilter.POLICY_PERMIT and is_matched:
block = False
@ -1352,7 +1355,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
self._adj_rib_in[nlri_str] = received_route
self._signal_bus.adj_rib_in_changed(self, received_route)
if block:
if not block:
# Update appropriate table with withdraws.
tm = self._core_service.table_manager
tm.learn_path(w_path)
@ -1444,7 +1447,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
self._adj_rib_in[nlri_str] = received_route
self._signal_bus.adj_rib_in_changed(self, received_route)
if block:
if not block:
if msg_rf == RF_RTC_UC \
and self._init_rtc_nlri_path is not None:
self._init_rtc_nlri_path.append(new_path)
@ -1508,7 +1511,7 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
self._adj_rib_in[nlri_str] = received_route
self._signal_bus.adj_rib_in_changed(self, received_route)
if block:
if not block:
# Update appropriate table with withdraws.
tm = self._core_service.table_manager
tm.learn_path(w_path)