示例#1
0
    def _new_best_path(self, new_best_path):
        old_best_path = self._best_path
        self._best_path = new_best_path
        LOG.debug('New best path selected for destination %s' % (self))

        # If old best path was withdrawn
        if (old_best_path and old_best_path not in self._known_path_list
                and self._sent_routes):
            # Have to clear sent_route list for this destination as
            # best path is removed.
            self._sent_routes = {}

        # Communicate that we have new best path to all qualifying
        # bgp-peers.
        pm = self._core_service.peer_manager
        pm.comm_new_best_to_bgp_peers(new_best_path)

        # withdraw old best path
        if old_best_path and self._sent_routes:
            for sent_route in self._sent_routes.values():
                sent_path = sent_route.path
                withdraw_clone = sent_path.clone(for_withdrawal=True)
                outgoing_route = OutgoingRoute(withdraw_clone)
                sent_route.sent_peer.enque_outgoing_msg(outgoing_route)
                LOG.debug('Sending withdrawal to %s for %s' %
                          (sent_route.sent_peer, outgoing_route))
                self._sent_routes = {}
示例#2
0
    def _best_path_lost(self):
        self._best_path = None

        if self._sent_routes:
            # We have to send update-withdraw to all peers to whom old best
            # path was sent.
            for sent_route in self._sent_routes.values():
                sent_path = sent_route.path
                withdraw_clone = sent_path.clone(for_withdrawal=True)
                outgoing_route = OutgoingRoute(withdraw_clone)
                sent_route.sent_peer.enque_outgoing_msg(outgoing_route)
                LOG.debug('Sending withdrawal to %s for %s' %
                          (sent_route.sent_peer, outgoing_route))

            # Have to clear sent_route list for this destination as
            # best path is removed.
            self._sent_routes = {}
示例#3
0
    def resend_sent(self, route_family, peer):
        """For given `peer` re-send sent paths.

        Parameters:
            - `route-family`: (RouteFamily) of the sent paths to re-send
            - `peer`: (Peer) peer for which we need to re-send sent paths
        """
        if peer not in self._peers.values():
            raise ValueError('Could not find given peer (%s)' % peer)

        if route_family not in SUPPORTED_GLOBAL_RF:
            raise ValueError(
                'Given route family (%s) is not supported.' % route_family
            )

        # Iterate over the global table for given afi, safi and enqueue
        # out-going routes.
        table = self._table_manager.get_global_table_by_route_family(
            route_family
        )

        for destination in table.itervalues():
            # Check if this destination's sent - routes include this peer.
            # i.e. check if this destinations was advertised and enqueue
            # the path only if it was. If the current best-path has not been
            # advertised before, it might already have a OutgoingRoute queued
            # to be sent to the peer.
            sent_routes = destination.sent_routes
            if sent_routes is None or len(sent_routes) == 0:
                continue
            for sent_route in sent_routes:
                if sent_route.sent_peer == peer:
                    # update med - if previously med was set per neighbor or
                    # wasn't set at all now it could have changed and we may
                    # need to set new value there
                    p = sent_route.path
                    if p.med_set_by_target_neighbor or p.get_pattr(
                            BGP_ATTR_TYPE_MULTI_EXIT_DISC) is None:
                        sent_route.path = \
                            clone_path_and_update_med_for_target_neighbor(
                                sent_route.path, peer.med
                            )

                    ogr = OutgoingRoute(sent_route.path,
                                        for_route_refresh=True)
                    peer.enque_outgoing_msg(ogr)
示例#4
0
    def withdraw_if_sent_to(self, peer):
        """Sends a withdraw for this destination to given `peer`.

        Check the records if we indeed advertise this destination to given peer
        and if so, creates a withdraw for advertised route and sends it to the
        peer.
        Parameter:
            - `peer`: (Peer) peer to send withdraw to
        """
        from ryu.services.protocols.bgp.peer import Peer
        if not isinstance(peer, Peer):
            raise TypeError('Currently we only support sending withdrawal'
                            ' to instance of peer')
        sent_route = self._sent_routes.pop(peer, None)
        if not sent_route:
            return False

        sent_path = sent_route.path
        withdraw_clone = sent_path.clone(for_withdrawal=True)
        outgoing_route = OutgoingRoute(withdraw_clone)
        sent_route.sent_peer.enque_outgoing_msg(outgoing_route)
        return True