diff options
-rw-r--r-- | ryu/services/protocols/bgp/application.py | 35 | ||||
-rw-r--r-- | ryu/services/protocols/bgp/bgpspeaker.py | 24 |
2 files changed, 59 insertions, 0 deletions
diff --git a/ryu/services/protocols/bgp/application.py b/ryu/services/protocols/bgp/application.py index df3e9b95..31cfb5f0 100644 --- a/ryu/services/protocols/bgp/application.py +++ b/ryu/services/protocols/bgp/application.py @@ -62,6 +62,7 @@ Integration with Other Applications following events to other Ryu applications. - ``EventBestPathChanged`` + - ``EventAdjRibInChanged`` - ``EventPeerDown`` - ``EventPeerUp`` @@ -191,6 +192,33 @@ class EventBestPathChanged(EventBase): self.is_withdraw = is_withdraw +class EventAdjRibInChanged(EventBase): + """ + Event called when any adj-RIB-in path is changed due to UPDATE messages + or remote peer's down. + + This event is the wrapper for ``adj_rib_in_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. + + ``peer_ip`` is the peer's IP address who sent this path. + + ``peer_as`` is the peer's AS number who sent this path. + """ + + def __init__(self, path, is_withdraw, peer_ip, peer_as): + super(EventAdjRibInChanged, self).__init__() + self.path = path + self.is_withdraw = is_withdraw + self.peer_ip = peer_ip + self.peer_as = peer_as + + class EventPeerDown(EventBase): """ Event called when the session to the remote peer goes down. @@ -233,6 +261,7 @@ class RyuBGPSpeaker(RyuApp): """ _EVENTS = [ EventBestPathChanged, + EventAdjRibInChanged, EventPeerDown, EventPeerUp, ] @@ -300,6 +329,8 @@ class RyuBGPSpeaker(RyuApp): settings.setdefault( 'best_path_change_handler', self._notify_best_path_changed_event) settings.setdefault( + 'adj_rib_in_change_handler', self._notify_adj_rib_in_changed_event) + settings.setdefault( 'peer_down_handler', self._notify_peer_down_event) settings.setdefault( 'peer_up_handler', self._notify_peer_up_event) @@ -330,6 +361,10 @@ class RyuBGPSpeaker(RyuApp): ev = EventBestPathChanged(ev.path, ev.is_withdraw) self.send_event_to_observers(ev) + def _notify_adj_rib_in_changed_event(self, ev, peer_ip, peer_as): + ev = EventAdjRibInChanged(ev.path, ev.is_withdraw, peer_ip, peer_as) + 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) diff --git a/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/services/protocols/bgp/bgpspeaker.py index 14e5eed9..5131c9ce 100644 --- a/ryu/services/protocols/bgp/bgpspeaker.py +++ b/ryu/services/protocols/bgp/bgpspeaker.py @@ -68,6 +68,7 @@ from ryu.services.protocols.bgp.api.prefix import ( FLOWSPEC_FAMILY_L2VPN, FLOWSPEC_RULES, FLOWSPEC_ACTIONS) +from ryu.services.protocols.bgp.model import ReceivedRoute from ryu.services.protocols.bgp.rtconf.common import LOCAL_AS from ryu.services.protocols.bgp.rtconf.common import ROUTER_ID from ryu.services.protocols.bgp.rtconf.common import CLUSTER_ID @@ -226,6 +227,7 @@ class BGPSpeaker(object): refresh_stalepath_time=DEFAULT_REFRESH_STALEPATH_TIME, refresh_max_eor_time=DEFAULT_REFRESH_MAX_EOR_TIME, best_path_change_handler=None, + adj_rib_in_change_handler=None, peer_down_handler=None, peer_up_handler=None, ssh_console=False, @@ -263,6 +265,12 @@ class BGPSpeaker(object): peer down. The handler is supposed to take one argument, the instance of an EventPrefix class instance. + ``adj_rib_in_change_handler``, if specified, is called when any + adj-RIB-in path is changed due to an update message or remote + peer down. The given handler should take three argument, the + instance of an EventPrefix class instance, str type peer's IP address + and int type peer's AS number. + ``peer_down_handler``, if specified, is called when BGP peering session goes down. @@ -315,6 +323,7 @@ class BGPSpeaker(object): self._core_start(settings) self._init_signal_listeners() self._best_path_change_handler = best_path_change_handler + self._adj_rib_in_change_handler = adj_rib_in_change_handler self._peer_down_handler = peer_down_handler self._peer_up_handler = peer_up_handler if ssh_console: @@ -351,6 +360,15 @@ class BGPSpeaker(object): if self._best_path_change_handler: self._best_path_change_handler(ev) + def _notify_adj_rib_in_changed(self, peer, route): + if not isinstance(route, ReceivedRoute): + return + + if self._adj_rib_in_change_handler: + self._adj_rib_in_change_handler( + EventPrefix(route.path, route.path.is_withdraw), + peer.ip_address, peer.remote_as) + def _init_signal_listeners(self): CORE_MANAGER.get_core_service()._signal_bus.register_listener( BgpSignalBus.BGP_BEST_PATH_CHANGED, @@ -359,6 +377,12 @@ class BGPSpeaker(object): info['is_withdraw']) ) CORE_MANAGER.get_core_service()._signal_bus.register_listener( + BgpSignalBus.BGP_ADJ_RIB_IN_CHANGED, + lambda _, info: + self._notify_adj_rib_in_changed(info['peer'], + info['received_route']) + ) + CORE_MANAGER.get_core_service()._signal_bus.register_listener( BgpSignalBus.BGP_ADJ_DOWN, lambda _, info: self._notify_peer_down(info['peer']) |