summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--ryu/services/protocols/bgp/application.py114
1 files changed, 114 insertions, 0 deletions
diff --git a/ryu/services/protocols/bgp/application.py b/ryu/services/protocols/bgp/application.py
index 9a85fe16..c1a9c43d 100644
--- a/ryu/services/protocols/bgp/application.py
+++ b/ryu/services/protocols/bgp/application.py
@@ -24,6 +24,7 @@ from ryu import cfg
from ryu.lib import hub
from ryu.utils import load_source
from ryu.base.app_manager import RyuApp
+from ryu.controller.event import EventBase
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 BIN_ERROR
@@ -87,7 +88,100 @@ def load_config(config_file):
raise ApplicationException(desc=str(e))
+class EventBestPathChanged(EventBase):
+ """
+ Event called when any best remote path is changed due to UPDATE messages
+ or remote peer's down.
+
+ This event is the wrapper for ``best_path_change_handler`` of
+ ``bgpspeaker.BGPSpeaker``.
+
+ ``path`` attribute contains an instance of ``info_base.base.Path``
+ subclasses.
+
+ If ``is_withdraw`` attribute is ``True``, ``path`` attribute has the
+ information of the withdraw route.
+ """
+
+ def __init__(self, path, is_withdraw):
+ super(EventBestPathChanged, self).__init__()
+ self.path = path
+ self.is_withdraw = is_withdraw
+
+
+class EventPeerDown(EventBase):
+ """
+ Event called when the session to the remote peer goes down.
+
+ This event is the wrapper for ``peer_down_handler`` of
+ ``bgpspeaker.BGPSpeaker``.
+
+ ``remote_ip`` attribute is the IP address of the remote peer.
+
+ ``remote_as`` attribute is the AS number of the remote peer.
+ """
+
+ def __init__(self, remote_ip, remote_as):
+ super(EventPeerDown, self).__init__()
+ self.remote_ip = remote_ip
+ self.remote_as = remote_as
+
+
+class EventPeerUp(EventBase):
+ """
+ Event called when the session to the remote peer goes up.
+
+ This event is the wrapper for ``peer_up_handler`` of
+ ``bgpspeaker.BGPSpeaker``.
+
+ ``remote_ip`` attribute is the IP address of the remote peer.
+
+ ``remote_as`` attribute is the AS number of the remote peer.
+ """
+
+ def __init__(self, remote_ip, remote_as):
+ super(EventPeerUp, self).__init__()
+ self.remote_ip = remote_ip
+ self.remote_as = remote_as
+
+
class RyuBGPSpeaker(RyuApp):
+ """
+ Base application for implementing BGP applications.
+
+ This application will notifies
+ - ``EventBestPathChanged``
+ - ``EventPeerDown``
+ - ``EventPeerUp``
+ to other BGP applications.
+ To catch these events, specify ``@set_ev_cls()`` decorator to the event
+ handlers in the Ryu applications.
+
+ Example::
+
+ ...
+ from ryu.base import app_manager
+ from ryu.controller.handler import set_ev_cls
+ from ryu.services.protocols.bgp import application as bgp_application
+ ...
+
+ class MyBGPApp(app_manager.RyuApp):
+ _CONTEXTS = {
+ 'ryubgpspeaker': bgp_application.RyuBGPSpeaker,
+ }
+
+ ...
+ @set_ev_cls(bgp_application.EventBestPathChanged)
+ def _best_patch_changed_handler(self, ev):
+ self.logger.info(
+ 'Best path changed: is_withdraw=%s, path=%s',
+ ev.is_withdraw, ev.path)
+ """
+ _EVENTS = [
+ EventBestPathChanged,
+ EventPeerDown,
+ EventPeerUp,
+ ]
def __init__(self, *args, **kwargs):
super(RyuBGPSpeaker, self).__init__(*args, **kwargs)
@@ -149,6 +243,14 @@ class RyuBGPSpeaker(RyuApp):
raise ApplicationException(
desc='Required BGP configuration missing: %s' % e)
+ # Set event notify handlers if no corresponding handler specified.
+ bgp_settings['best_path_change_handler'] = settings.get(
+ 'best_path_change_handler', self._notify_best_path_changed_event)
+ bgp_settings['peer_down_handler'] = settings.get(
+ 'peer_down_handler', self._notify_peer_down_event)
+ bgp_settings['peer_up_handler'] = settings.get(
+ 'peer_up_handler', self._notify_peer_up_event)
+
# Get optional settings.
bgp_settings[BGP_SERVER_PORT] = settings.get(
BGP_SERVER_PORT, DEFAULT_BGP_SERVER_PORT)
@@ -175,6 +277,18 @@ class RyuBGPSpeaker(RyuApp):
LOG.debug('Adding routes...')
self._add_routes(settings.get('routes', []))
+ def _notify_best_path_changed_event(self, ev):
+ ev = EventBestPathChanged(ev.path, ev.is_withdraw)
+ self.send_event_to_observers(ev)
+
+ def _notify_peer_down_event(self, remote_ip, remote_as):
+ ev = EventPeerDown(remote_ip, remote_as)
+ self.send_event_to_observers(ev)
+
+ def _notify_peer_up_event(self, remote_ip, remote_as):
+ ev = EventPeerUp(remote_ip, remote_as)
+ self.send_event_to_observers(ev)
+
def _add_neighbors(self, settings):
"""
Add BGP neighbors from the given settings.