def add_bgp_speaker(self, speaker_as): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if curr_speaker is not None: raise bgp_driver_exc.BgpSpeakerAlreadyScheduled( current_as=speaker_as, rtid=self.routerid) # Ryu can only support One speaker if self.cache.get_hosted_bgp_speakers_count() == 1: raise bgp_driver_exc.BgpSpeakerMaxScheduled(count=1) # Validate input parameters. # speaker_as must be an integer in the allowed range. utils.validate_as_num('local_as', speaker_as) # Notify Ryu about BGP Speaker addition. curr_speaker = bgpspeaker.BGPSpeaker( as_number=speaker_as, router_id=self.routerid, bgp_server_port=179, best_path_change_handler=self.best_path_change_cb, peer_down_handler=self.bgp_peer_down_cb, peer_up_handler=self.bgp_peer_up_cb) LOG.info( _LI('Added BGP Speaker for local_as=%(as)d with ' 'router_id= %(rtid)s.'), { 'as': speaker_as, 'rtid': self.routerid }) self.cache.put_bgp_speaker(speaker_as, curr_speaker)
def bind(self, context, agents, bgp_speaker_id): """Bind the BgpSpeaker to a BgpDrAgent.""" bound_agents = agents[:] for agent in agents: # saving agent_id to use it after rollback to avoid # DetachedInstanceError agent_id = agent.id binding = bgp_dras_db.BgpSpeakerDrAgentBinding() binding.agent_id = agent_id binding.bgp_speaker_id = bgp_speaker_id try: with context.session.begin(subtransactions=True): context.session.add(binding) except db_exc.DBDuplicateEntry: # it's totally ok, someone just did our job! bound_agents.remove(agent) LOG.info(_LI('BgpDrAgent %s already present'), agent_id) LOG.debug( 'BgpSpeaker %(bgp_speaker_id)s is scheduled to be ' 'hosted by BgpDrAgent %(agent_id)s', { 'bgp_speaker_id': bgp_speaker_id, 'agent_id': agent_id }) super(BgpDrAgentFilter, self).bind(context, bound_agents, bgp_speaker_id)
def __init__(self, cfg): LOG.info(_LI('Initializing Ryu driver for BGP Speaker functionality.')) self._read_config(cfg) # Note: Even though Ryu can only support one BGP speaker as of now, # we have tried making the framework generic for the future purposes. self.cache = utils.BgpMultiSpeakerCache()
def add_bgp_peer(self, speaker_as, peer_ip, peer_as, auth_type='none', password=None): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate peer_ip and peer_as. utils.validate_as_num('remote_as', peer_as) utils.validate_string(peer_ip) utils.validate_auth(auth_type, password) # Notify Ryu about BGP Peer addition curr_speaker.neighbor_add(address=peer_ip, remote_as=peer_as, password=password, connect_mode=CONNECT_MODE_ACTIVE) LOG.info( _LI('Added BGP Peer %(peer)s for remote_as=%(as)d to ' 'BGP Speaker running for local_as=%(local_as)d.'), { 'peer': peer_ip, 'as': peer_as, 'local_as': speaker_as })
def add_bgp_speaker(self, speaker_as): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if curr_speaker is not None: raise bgp_driver_exc.BgpSpeakerAlreadyScheduled( current_as=speaker_as, rtid=self.routerid) # Ryu can only support One speaker if self.cache.get_hosted_bgp_speakers_count() == 1: raise bgp_driver_exc.BgpSpeakerMaxScheduled(count=1) # Validate input parameters. # speaker_as must be an integer in the allowed range. utils.validate_as_num('local_as', speaker_as) # Notify Ryu about BGP Speaker addition. # Please note: Since, only the route-advertisement support is # implemented we are explicitly setting the bgp_server_port # attribute to 0 which disables listening on port 179. curr_speaker = bgpspeaker.BGPSpeaker( as_number=speaker_as, router_id=self.routerid, bgp_server_port=0, best_path_change_handler=best_path_change_cb, peer_down_handler=bgp_peer_down_cb, peer_up_handler=bgp_peer_up_cb) LOG.info( _LI('Added BGP Speaker for local_as=%(as)d with ' 'router_id= %(rtid)s.'), { 'as': speaker_as, 'rtid': self.routerid }) self.cache.put_bgp_speaker(speaker_as, curr_speaker)
def best_path_change_cb(event): LOG.info(_LI("Best path change observed. cidr=%(prefix)s, " "nexthop=%(nexthop)s, remote_as=%(remote_as)d, " "is_withdraw=%(is_withdraw)s"), {'prefix': event.prefix, 'nexthop': event.nexthop, 'remote_as': event.remote_as, 'is_withdraw': event.is_withdraw})
def add_vrf_speaker_assoc(self, context, vrf_id, speaker_association): speaker_id = speaker_association['speaker_id'] LOG.info( _LI("Add speaker association %(speaker_id)s " "for BGPVRF %(vrf_id)s"), { 'speaker_id': speaker_id, 'vrf_id': vrf_id }) try: with context.session.begin(subtransactions=True): speaker_assoc_db = BgpSpeakerVrfBinding( id=uuidutils.generate_uuid(), vrf_id=vrf_id, speaker_id=speaker_id) context.session.add(speaker_assoc_db) return self._make_speaker_assoc_dict(speaker_assoc_db) except db_exc.DBDuplicateEntry: LOG.warning( _LW("Speaker %(speaker_id)s is already associated to " "BGPVRF %(vrf_id)s"), { 'speaker_id': speaker_id, 'vrf_id': vrf_id }) raise vrf_ext.BGPVRFSpeakerAssocAlreadyExists( vrf_id=vrf_id, speaker_id=speaker_id)
def add_bgp_speaker(self, speaker_as): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if curr_speaker is not None: raise bgp_driver_exc.BgpSpeakerAlreadyScheduled( current_as=speaker_as, rtid=self.routerid) # Ryu can only support One speaker if self.cache.get_hosted_bgp_speakers_count() == 1: raise bgp_driver_exc.BgpSpeakerMaxScheduled(count=1) # Validate input parameters. # speaker_as must be an integer in the allowed range. utils.validate_as_num('local_as', speaker_as) # Notify Ryu about BGP Speaker addition. # Please note: Since, only the route-advertisement support is # implemented we are explicitly setting the bgp_server_port # attribute to 0 which disables listening on port 179. curr_speaker = bgpspeaker.BGPSpeaker(as_number=speaker_as, router_id=self.routerid, bgp_server_port=0, best_path_change_handler=best_path_change_cb, peer_down_handler=bgp_peer_down_cb, peer_up_handler=bgp_peer_up_cb) LOG.info(_LI('Added BGP Speaker for local_as=%(as)d with ' 'router_id= %(rtid)s.'), {'as': speaker_as, 'rtid': self.routerid}) self.cache.put_bgp_speaker(speaker_as, curr_speaker)
def _report_state(self): LOG.debug("Report state task started") try: self.agent_state.get('configurations').update( self.cache.get_state()) ctx = context.get_admin_context_without_session() agent_status = self.state_rpc.report_state(ctx, self.agent_state, True) if agent_status == agent_consts.AGENT_REVIVED: LOG.info(_LI("Agent has just been revived. " "Scheduling full sync")) self.schedule_full_resync( reason=_("Agent has just been revived")) except AttributeError: # This means the server does not support report_state LOG.warning(_LW("Neutron server does not support state report. " "State report for this agent will be disabled.")) self.heartbeat.stop() self.run() return except Exception: LOG.exception(_LE("Failed reporting state!")) return if self.agent_state.pop('start_flag', None): self.run()
def bgp_peer_up_cb(self, remote_ip, remote_as): LOG.info(_LI('BGP Peer %(peer_ip)s for remote_as=%(peer_as)d is UP.'), { 'peer_ip': remote_ip, 'peer_as': remote_as }) if self._peer_up_callback: self._peer_up_callback(remote_ip=remote_ip, remote_as=remote_as)
def _read_config(self, cfg): if cfg is None or cfg.bgp_router_id is None: # If either cfg or router_id is not specified, raise voice LOG.error(_LE('BGP router-id MUST be specified for the correct ' 'functional working.')) else: self.routerid = cfg.bgp_router_id LOG.info(_LI('Initialized Ryu BGP Speaker driver interface with ' 'bgp_router_id=%s'), self.routerid)
def best_path_change_cb(event): LOG.info( _LI("Best path change observed. cidr=%(prefix)s, " "nexthop=%(nexthop)s, remote_as=%(remote_as)d, " "is_withdraw=%(is_withdraw)s"), { 'prefix': event.prefix, 'nexthop': event.nexthop, 'remote_as': event.remote_as, 'is_withdraw': event.is_withdraw })
def delete_bgp_speaker(self, speaker_as): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Notify Ryu about BGP Speaker deletion curr_speaker.shutdown() LOG.info(_LI('Removed BGP Speaker for local_as=%(as)d with ' 'router_id=%(rtid)s.'), {'as': speaker_as, 'rtid': self.routerid}) self.cache.remove_bgp_speaker(speaker_as)
def _read_config(self, cfg): if cfg is None or cfg.bgp_router_id is None: # If either cfg or router_id is not specified, raise voice LOG.error( _LE('BGP router-id MUST be specified for the correct ' 'functional working.')) else: self.routerid = cfg.bgp_router_id LOG.info( _LI('Initialized Ryu BGP Speaker driver interface with ' 'bgp_router_id=%s'), self.routerid)
def get_bgp_speaker_statistics(self, speaker_as): LOG.info(_LI('Collecting BGP Speaker statistics for local_as=%d.'), speaker_as) curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # TODO(vikram): Filter and return the necessary information. # Will be done as part of new RFE requirement # https://bugs.launchpad.net/neutron/+bug/1527993 return curr_speaker.neighbor_state_get()
def delete_bgp_peer(self, speaker_as, peer_ip): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate peer_ip. It must be a string. utils.validate_string(peer_ip) # Notify Ryu about BGP Peer removal curr_speaker.neighbor_del(address=peer_ip) LOG.info(_LI('Removed BGP Peer %(peer)s from BGP Speaker ' 'running for local_as=%(local_as)d.'), {'peer': peer_ip, 'local_as': speaker_as})
def best_path_change_cb(self, event): LOG.info( _LI("Best path change observed. cidr=%(prefix)s, " "nexthop=%(nexthop)s, remote_as=%(remote_as)d, " "is_withdraw=%(is_withdraw)s"), { 'prefix': event.prefix, 'nexthop': event.nexthop, 'remote_as': event.remote_as, 'is_withdraw': event.is_withdraw }) if self._path_change_callback: normalized_event = self._normalize_path_event(event) self._path_change_callback(**normalized_event)
def get_bgp_peer_statistics(self, speaker_as, peer_ip): LOG.info(_LI('Collecting BGP Peer statistics for peer_ip=%(peer)s, ' 'running in speaker_as=%(speaker_as)d '), {'peer': peer_ip, 'speaker_as': speaker_as}) curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # TODO(vikram): Filter and return the necessary information. # Will be done as part of new RFE requirement # https://bugs.launchpad.net/neutron/+bug/1527993 return curr_speaker.neighbor_state_get(address=peer_ip)
def withdraw_route(self, speaker_as, cidr, nexthop=None): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate cidr. It must be a string. utils.validate_string(cidr) # Notify Ryu about route withdrawal curr_speaker.prefix_del(prefix=cidr) LOG.info(_LI('Route cidr=%(prefix)s is withdrawn from BGP Speaker ' 'running for local_as=%(local_as)d.'), {'prefix': cidr, 'local_as': speaker_as})
def remove_vrf_speaker_assoc(self, context, vrf_id, speaker_association): speaker_id = speaker_association['speaker_id'] LOG.info( _LI("deleting speaker association %(speaker_id)s " "for BGPVRF %(vrf_id)s"), { 'speaker_id': speaker_id, 'vrf_id': vrf_id }) with context.session.begin(): speaker_assoc_db = self._get_speaker_assoc(context, vrf_id, speaker_id) speaker_assoc = self._make_speaker_assoc_dict(speaker_assoc_db) context.session.delete(speaker_assoc_db) return speaker_assoc
def delete_bgp_speaker(self, speaker_as): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Notify Ryu about BGP Speaker deletion curr_speaker.shutdown() LOG.info( _LI('Removed BGP Speaker for local_as=%(as)d with ' 'router_id=%(rtid)s.'), { 'as': speaker_as, 'rtid': self.routerid }) self.cache.remove_bgp_speaker(speaker_as)
def advertise_evpn_route(self, speaker_as, route_type, route_dist, esi=0, ethernet_tag_id=None, mac_addr=None, ip_addr=None, ip_prefix=None, gw_ip_addr=None, vni=None, next_hop=None, tunnel_type=None): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate parameters that must be strings. utils.validate_string(route_dist) utils.validate_string(mac_addr) utils.validate_string(ip_addr) utils.validate_string(gw_ip_addr) utils.validate_string(next_hop) utils.validate_string(tunnel_type) kwargs = { 'esi': esi, 'ethernet_tag_id': ethernet_tag_id, 'mac_addr': mac_addr, 'ip_addr': ip_addr, 'ip_prefix': ip_prefix, 'gw_ip_addr': gw_ip_addr, 'vni': vni, 'next_hop': next_hop, 'tunnel_type': tunnel_type } curr_speaker.evpn_prefix_add( self.convert_to_local_route_type(route_type), route_dist, **kwargs) LOG.info( _LI('EVPN route type %(route_type)s for RD %(rd)s is ' 'advertised for BGP Speaker running for ' 'local_as=%(local_as)d attributes: %(attributes)s.'), { 'rd': route_dist, 'route_type': route_type, 'local_as': speaker_as, 'attributes': kwargs })
def remove_vrf_router_assoc(self, context, vrf_id, router_association): LOG.debug("association %s", router_association) router_id = router_association['router_id'] LOG.info( _LI("deleting vrf %(vrf_id)s router %(router_id)s " "association"), { 'vrf_id': vrf_id, 'router_id': router_id }) with context.session.begin(): router_assoc_db = self._get_router_assoc(context, vrf_id, router_id) router_assoc = self._make_router_assoc_dict(router_assoc_db) context.session.delete(router_assoc_db) return router_assoc
def get_bgp_peer_statistics(self, speaker_as, peer_ip): LOG.info( _LI('Collecting BGP Peer statistics for peer_ip=%(peer)s, ' 'running in speaker_as=%(speaker_as)d '), { 'peer': peer_ip, 'speaker_as': speaker_as }) curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # TODO(vikram): Filter and return the necessary information. # Will be done as part of new RFE requirement # https://bugs.launchpad.net/neutron/+bug/1527993 return curr_speaker.neighbor_state_get(address=peer_ip)
def advertise_route(self, speaker_as, cidr, nexthop): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate cidr and nexthop. Both must be strings. utils.validate_string(cidr) utils.validate_string(nexthop) # Notify Ryu about route advertisement curr_speaker.prefix_add(prefix=cidr, next_hop=nexthop) LOG.info(_LI('Route cidr=%(prefix)s, nexthop=%(nexthop)s is ' 'advertised for BGP Speaker running for ' 'local_as=%(local_as)d.'), {'prefix': cidr, 'nexthop': nexthop, 'local_as': speaker_as})
def delete_vrf(self, speaker_as, route_dist): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate route_dist. It must be a string. utils.validate_string(route_dist) # Notify Ryu about a deleted VRF curr_speaker.vrf_del(route_dist=route_dist) LOG.info( _LI('VRF for RD %(rd)s is no longer advertised for BGP ' 'Speaker running for local_as=%(local_as)d.'), { 'rd': route_dist, 'local_as': speaker_as })
def withdraw_route(self, speaker_as, cidr, nexthop=None): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate cidr. It must be a string. utils.validate_string(cidr) # Notify Ryu about route withdrawal curr_speaker.prefix_del(prefix=cidr) LOG.info( _LI('Route cidr=%(prefix)s is withdrawn from BGP Speaker ' 'running for local_as=%(local_as)d.'), { 'prefix': cidr, 'local_as': speaker_as })
def delete_bgp_peer(self, speaker_as, peer_ip): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate peer_ip. It must be a string. utils.validate_string(peer_ip) # Notify Ryu about BGP Peer removal curr_speaker.neighbor_del(address=peer_ip) LOG.info( _LI('Removed BGP Peer %(peer)s from BGP Speaker ' 'running for local_as=%(local_as)d.'), { 'peer': peer_ip, 'local_as': speaker_as })
def add_bgp_peer(self, speaker_as, peer_ip, peer_as, auth_type='none', password=None, enable_evpn=None, hold_time=None, connect_mode=CONNECT_MODE_ACTIVE): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate peer_ip and peer_as. utils.validate_as_num('remote_as', peer_as) ip_version = utils.validate_ip_addr(peer_ip) utils.validate_auth(auth_type, password) if password is not None: password = encodeutils.to_utf8(password) kwargs = {} if enable_evpn is not None: kwargs['enable_evpn'] = enable_evpn if hold_time is not None: kwargs['hold_time'] = hold_time # Notify Ryu about BGP Peer addition if ip_version == lib_consts.IP_VERSION_4: enable_ipv4 = True enable_ipv6 = False else: enable_ipv4 = False enable_ipv6 = True curr_speaker.neighbor_add(address=peer_ip, remote_as=peer_as, enable_ipv4=enable_ipv4, enable_ipv6=enable_ipv6, password=password, connect_mode=connect_mode, **kwargs) LOG.info( _LI('Added BGP Peer %(peer)s for remote_as=%(as)d to ' 'BGP Speaker running for local_as=%(local_as)d.'), { 'peer': peer_ip, 'as': peer_as, 'local_as': speaker_as })
def add_vrf(self, speaker_as, route_dist, import_rts, export_rts, vrf_type): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate route_dist. It must be a string. utils.validate_string(route_dist) # Notify Ryu about a new VRF curr_speaker.vrf_add(route_dist=route_dist, import_rts=import_rts, export_rts=export_rts, route_family=self.get_vrf_type(vrf_type)) LOG.info( _LI('VRF for RD %(rd)s is advertised for BGP Speaker ' 'running for local_as=%(local_as)d.'), { 'rd': route_dist, 'local_as': speaker_as })
def add_bgp_peer(self, speaker_as, peer_ip, peer_as, auth_type='none', password=None): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate peer_ip and peer_as. utils.validate_as_num('remote_as', peer_as) utils.validate_string(peer_ip) utils.validate_auth(auth_type, password) # Notify Ryu about BGP Peer addition curr_speaker.neighbor_add(address=peer_ip, remote_as=peer_as, password=password, connect_mode=CONNECT_MODE_ACTIVE) LOG.info(_LI('Added BGP Peer %(peer)s for remote_as=%(as)d to ' 'BGP Speaker running for local_as=%(local_as)d.'), {'peer': peer_ip, 'as': peer_as, 'local_as': speaker_as})
def advertise_route(self, speaker_as, cidr, nexthop): curr_speaker = self.cache.get_bgp_speaker(speaker_as) if not curr_speaker: raise bgp_driver_exc.BgpSpeakerNotAdded(local_as=speaker_as, rtid=self.routerid) # Validate cidr and nexthop. Both must be strings. utils.validate_string(cidr) utils.validate_string(nexthop) # Notify Ryu about route advertisement curr_speaker.prefix_add(prefix=cidr, next_hop=nexthop) LOG.info( _LI('Route cidr=%(prefix)s, nexthop=%(nexthop)s is ' 'advertised for BGP Speaker running for ' 'local_as=%(local_as)d.'), { 'prefix': cidr, 'nexthop': nexthop, 'local_as': speaker_as })
def bind(self, context, agents, bgp_speaker_id): """Bind the BgpSpeaker to a BgpDrAgent.""" bound_agents = agents[:] for agent in agents: # saving agent_id to use it after rollback to avoid # DetachedInstanceError agent_id = agent.id binding = bgp_dras_db.BgpSpeakerDrAgentBinding() binding.agent_id = agent_id binding.bgp_speaker_id = bgp_speaker_id try: with context.session.begin(subtransactions=True): context.session.add(binding) except db_exc.DBDuplicateEntry: # it's totally ok, someone just did our job! bound_agents.remove(agent) LOG.info(_LI('BgpDrAgent %s already present'), agent_id) LOG.debug('BgpSpeaker %(bgp_speaker_id)s is scheduled to be ' 'hosted by BgpDrAgent %(agent_id)s', {'bgp_speaker_id': bgp_speaker_id, 'agent_id': agent_id}) super(BgpDrAgentFilter, self).bind(context, bound_agents, bgp_speaker_id)
def agent_updated(self, context, payload): """Handle the agent_updated notification event.""" self.schedule_full_resync( reason=_("BgpDrAgent updated: %s") % payload) LOG.info(_LI("agent_updated by server side %s!"), payload)
def bgp_peer_down_cb(remote_ip, remote_as): LOG.info(_LI('BGP Peer %(peer_ip)s for remote_as=%(peer_as)d went DOWN.'), {'peer_ip': remote_ip, 'peer_as': remote_as})
def bgp_peer_up_cb(remote_ip, remote_as): LOG.info(_LI('BGP Peer %(peer_ip)s for remote_as=%(peer_as)d is UP.'), {'peer_ip': remote_ip, 'peer_as': remote_as})
def bgp_peer_up_cb(remote_ip, remote_as): LOG.info(_LI('BGP Peer %(peer_ip)s for remote_as=%(peer_as)d is UP.'), { 'peer_ip': remote_ip, 'peer_as': remote_as })
def bgp_peer_down_cb(remote_ip, remote_as): LOG.info(_LI('BGP Peer %(peer_ip)s for remote_as=%(peer_as)d went DOWN.'), { 'peer_ip': remote_ip, 'peer_as': remote_as })
def after_start(self): LOG.info(_LI("BGP dynamic routing agent started"))
def after_start(self): self.run() LOG.info(_LI("BGP Dynamic Routing agent started"))