diff options
-rw-r--r-- | ryu/services/protocols/bgp/model.py | 35 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/peer.py | 40 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/signals/emit.py | 12 |
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}) |