summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ryu/services/protocols/bgp/model.py35
-rw-r--r--ryu/services/protocols/bgp/peer.py40
-rw-r--r--ryu/services/protocols/bgp/signals/emit.py12
3 files changed, 85 insertions, 2 deletions
diff --git a/ryu/services/protocols/bgp/model.py b/ryu/services/protocols/bgp/model.py
index 51c8bb02..86af6f49 100644
--- a/ryu/services/protocols/bgp/model.py
+++ b/ryu/services/protocols/bgp/model.py
@@ -19,6 +19,7 @@
sessions.
"""
import logging
+from time import localtime
LOG = logging.getLogger('bgpspeaker.model')
@@ -130,7 +131,7 @@ class SentRoute(object):
about a particular BGP destination.
"""
- def __init__(self, path, peer):
+ def __init__(self, path, peer, filtered=None, timestamp=None):
assert(path and hasattr(peer, 'version_num'))
self.path = path
@@ -138,6 +139,13 @@ class SentRoute(object):
# Peer to which this path was sent.
self._sent_peer = peer
+ self.filtered = filtered
+
+ if timestamp:
+ self.timestamp = timestamp
+ else:
+ self.timestamp = localtime()
+
# Automatically generated.
#
# self.next_sent_route
@@ -146,3 +154,28 @@ class SentRoute(object):
@property
def sent_peer(self):
return self._sent_peer
+
+
+class ReceivedRoute(object):
+ """Holds the information that has been received to one sinks
+ about a particular BGP destination.
+ """
+
+ def __init__(self, path, peer, filtered=None, timestamp=None):
+ assert(path and hasattr(peer, 'version_num'))
+
+ self.path = path
+
+ # Peer to which this path was received.
+ self._received_peer = peer
+
+ self.filtered = filtered
+
+ if timestamp:
+ self.timestamp = timestamp
+ else:
+ self.timestamp = localtime()
+
+ @property
+ def received_peer(self):
+ return self._received_peer
diff --git a/ryu/services/protocols/bgp/peer.py b/ryu/services/protocols/bgp/peer.py
index 5d5debec..fa0fe27c 100644
--- a/ryu/services/protocols/bgp/peer.py
+++ b/ryu/services/protocols/bgp/peer.py
@@ -30,6 +30,7 @@ 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.info_base.base import PrefixList
+from ryu.services.protocols.bgp.model import ReceivedRoute
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
@@ -330,6 +331,18 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
self._sent_init_non_rtc_update = False
self._init_rtc_nlri_path = []
+ # in-bound filters
+ self._in_filters = self._neigh_conf.in_filter
+
+ # out-bound filters
+ self._out_filters = self._neigh_conf.out_filter
+
+ # Adj-rib-in
+ self._adj_rib_in = {}
+
+ # Adj-rib-out
+ self._adj_rib_out = {}
+
@property
def remote_as(self):
return self._neigh_conf.remote_as
@@ -553,6 +566,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
blocked_cause = prefix_list.prefix + ' - DENY'
break
+ nlri_str = outgoing_route.path.nlri.formatted_nlri_str
+ sent_route = SentRoute(outgoing_route.path, self, block)
+ self._adj_rib_out[nlri_str] = sent_route
+ self._signal_bus.adj_rib_out_changed(self, sent_route)
+
# TODO(PH): optimized by sending several prefixes per update.
# Construct and send update message.
if allow_to_send:
@@ -569,7 +587,6 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
if (not outgoing_route.path.is_withdraw and
not outgoing_route.for_route_refresh):
# Update the destination with new sent route.
- sent_route = SentRoute(outgoing_route.path, self)
tm = self._core_service.table_manager
tm.remember_sent_route(sent_route)
@@ -1253,6 +1270,12 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
LOG.debug('Extracted paths from Update msg.: %s' % new_path)
block, blocked_cause = self._apply_in_filter(new_path)
+
+ nlri_str = new_path.nlri.formatted_nlri_str
+ received_route = ReceivedRoute(new_path, self, block)
+ self._adj_rib_in[nlri_str] = received_route
+ self._signal_bus.adj_rib_in_changed(self, received_route)
+
if not block:
# Update appropriate table with new paths.
tm = self._core_service.table_manager
@@ -1308,6 +1331,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
)
block, blocked_cause = self._apply_in_filter(w_path)
+
+ received_route = ReceivedRoute(w_path, self, block)
+ self._adj_rib_in[nlri_str] = received_route
+ self._signal_bus.adj_rib_in_changed(self, received_route)
+
if block:
# Update appropriate table with withdraws.
tm = self._core_service.table_manager
@@ -1394,6 +1422,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
LOG.debug('Extracted paths from Update msg.: %s' % new_path)
block, blocked_cause = self._apply_in_filter(new_path)
+
+ received_route = ReceivedRoute(new_path, self, block)
+ self._adj_rib_in[nlri_str] = received_route
+ self._signal_bus.adj_rib_in_changed(self, received_route)
+
if block:
if msg_rf == RF_RTC_UC \
and self._init_rtc_nlri_path is not None:
@@ -1452,6 +1485,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
is_withdraw=True
)
block, blocked_cause = self._apply_in_filter(w_path)
+
+ received_route = ReceivedRoute(w_path, self, block)
+ self._adj_rib_in[nlri_str] = received_route
+ self._signal_bus.adj_rib_in_changed(self, received_route)
+
if block:
# Update appropriate table with withdraws.
tm = self._core_service.table_manager
diff --git a/ryu/services/protocols/bgp/signals/emit.py b/ryu/services/protocols/bgp/signals/emit.py
index 890c1bc7..f015fdb8 100644
--- a/ryu/services/protocols/bgp/signals/emit.py
+++ b/ryu/services/protocols/bgp/signals/emit.py
@@ -12,6 +12,8 @@ class BgpSignalBus(SignalBus):
'core', 'vrf', 'config', 'stats', 'changed'
)
BGP_BEST_PATH_CHANGED = ('core', 'best', 'changed')
+ BGP_ADJ_RIB_IN_CHANGED = ('core', 'adj', 'rib', 'in', 'changed')
+ BGP_ADJ_RIB_OUT_CHANGED = ('core', 'adj', 'rib', 'out', 'changed')
def bgp_error(self, peer, code, subcode, reason):
return self.emit_signal(
@@ -59,3 +61,13 @@ class BgpSignalBus(SignalBus):
return self.emit_signal(
self.BGP_BEST_PATH_CHANGED,
{'path': path, 'is_withdraw': is_withdraw})
+
+ def adj_rib_in_changed(self, peer, received_route):
+ return self.emit_signal(
+ self.BGP_ADJ_RIB_IN_CHANGED,
+ {'peer': peer, 'received_route': received_route})
+
+ def adj_rib_out_changed(self, peer, sent_route):
+ return self.emit_signal(
+ self.BGP_ADJ_RIB_OUT_CHANGED,
+ {'peer': peer, 'sent_route': sent_route})