def register_switch_address(addr, interval=None): """ Registers a new address to initiate connection to switch. Registers a new IP address and port pair of switch to let os_ken.controller.controller.OpenFlowController to try to initiate connection to switch. :param addr: A tuple of (host, port) pair of switch. :param interval: Interval in seconds to try to connect to switch """ assert len(addr) == 2 assert ip.valid_ipv4(addr[0]) or ip.valid_ipv6(addr[0]) ofp_handler = app_manager.lookup_service_brick(ofp_event.NAME) _TMP_ADDRESSES[addr] = interval def _retry_loop(): # Delays registration if ofp_handler is not started yet while True: if ofp_handler.controller is not None: for a, i in _TMP_ADDRESSES.items(): ofp_handler.controller.spawn_client_loop(a, i) hub.sleep(1) break hub.sleep(1) hub.spawn(_retry_loop)
def start(self): super(RemoteOvsdb, self).start() t = hub.spawn(self._run_thread, self._idl_loop) self.threads.append(t) t = hub.spawn(self._run_thread, self._event_proxy_loop) self.threads.append(t)
def _wait_bpdu_timer(self): time_exceed = False while True: self.wait_timer_event = hub.Event() message_age = (self.designated_times.message_age if self.designated_times else 0) timer = self.port_times.max_age - message_age timeout = hub.Timeout(timer) try: self.wait_timer_event.wait() except hub.Timeout as t: if t is not timeout: err_msg = 'Internal error. Not my timeout.' raise OSKenException(msg=err_msg) self.logger.info('[port=%d] Wait BPDU timer is exceeded.', self.ofport.port_no, extra=self.dpid_str) time_exceed = True finally: timeout.cancel() self.wait_timer_event = None if time_exceed: break if time_exceed: # Bridge.recalculate_spanning_tree hub.spawn(self.wait_bpdu_timeout)
def _start_recv(self): if os.path.exists(SOCKFILE): os.unlink(SOCKFILE) self.sock = hub.socket.socket(hub.socket.AF_UNIX, hub.socket.SOCK_DGRAM) self.sock.bind(SOCKFILE) hub.spawn(self._recv_loop)
def peer_accept_handler(self, new_sock, addr): peer = Peer(self._rpc_events) table = { rpc.MessageType.REQUEST: peer._handle_vrrp_request, } peer._endpoint = rpc.EndPoint(new_sock, disp_table=table) self._peers.append(peer) hub.spawn(self._peer_loop_thread, peer)
def __init__(self, *args, **kwargs): super(OFConfigClient, self).__init__(*args, **kwargs) self.switch = capable_switch.OFCapableSwitch( host=HOST, port=PORT, username=USERNAME, password=PASSWORD, unknown_host_cb=lambda host, fingeprint: True) hub.spawn(self._do_of_config)
def _start_recv_nw_sock(self, port): self.nwsock = hub.socket.socket(hub.socket.AF_INET, hub.socket.SOCK_STREAM) self.nwsock.setsockopt(hub.socket.SOL_SOCKET, hub.socket.SO_REUSEADDR, 1) self.nwsock.bind(('0.0.0.0', port)) self.nwsock.listen(5) hub.spawn(self._accept_loop_nw_sock)
def _do_leave(self, leave, in_port, msg): """the process when the snooper received a LEAVE message.""" datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser # check whether the querier port has been specified. if not self._to_querier.get(dpid): self.logger.info("no querier exists.") return # save this LEAVE message and reset the condition of the port # that received this message. self._to_hosts.setdefault(dpid, {}) self._to_hosts[dpid].setdefault(leave.address, { 'replied': False, 'leave': None, 'ports': {} }) self._to_hosts[dpid][leave.address]['leave'] = msg self._to_hosts[dpid][leave.address]['ports'][in_port] = { 'out': False, 'in': False } # create a specific query. timeout = igmp.LAST_MEMBER_QUERY_INTERVAL res_igmp = igmp.igmp(msgtype=igmp.IGMP_TYPE_QUERY, maxresp=timeout * 10, csum=0, address=leave.address) res_ipv4 = ipv4.ipv4(total_length=len(ipv4.ipv4()) + len(res_igmp), proto=inet.IPPROTO_IGMP, ttl=1, src=self._to_querier[dpid]['ip'], dst=igmp.MULTICAST_IP_ALL_HOST) res_ether = ethernet.ethernet(dst=igmp.MULTICAST_MAC_ALL_HOST, src=self._to_querier[dpid]['mac'], ethertype=ether.ETH_TYPE_IP) res_pkt = packet.Packet() res_pkt.add_protocol(res_ether) res_pkt.add_protocol(res_ipv4) res_pkt.add_protocol(res_igmp) res_pkt.serialize() # send a specific query to the host that sent this message. actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)] self._do_packet_out(datapath, res_pkt.data, in_port, actions) # wait for REPORT messages. hub.spawn(self._do_timeout_for_leave, timeout, datapath, leave.address, in_port)
def agent_main_wrapper(bridge_classes): try: ovs_agent.main(bridge_classes) except Exception: with excutils.save_and_reraise_exception(): LOG.exception("Agent main thread died of an exception") finally: # The following call terminates os-ken's AppManager.run_apps(), # which is needed for clean shutdown of an agent process. # The close() call must be called in another thread, otherwise # it suicides and ends prematurely. hub.spawn(app_manager.AppManager.get_instance().close)
def _switch_enter_handler(self, ev): if self.start_main: return switches = topo_api.get_switch(self) if len(switches) < 2: return self.start_main = True app_mgr = app_manager.AppManager.get_instance() self.logger.debug('%s', app_mgr.applications) self.switches = app_mgr.applications['switches'] hub.spawn(self._main)
def start(self): self.is_active = True self.sock.settimeout(GLOBAL_CONF.socket_timeout) self._threads.append(hub.spawn(self._send_loop)) self._threads.append(hub.spawn(self._recv_loop)) self.server.send_event_to_observers( zserver_event.EventZClientConnected(self)) hub.joinall(self._threads) self.server.send_event_to_observers( zserver_event.EventZClientDisconnected(self))
def __init__(self, *args, **kwargs): super(RpcVRRPManager, self).__init__(*args, **kwargs) self.CONF.register_opts([ cfg.IntOpt('vrrp-rpc-port', default=VRRP_RPC_PORT, help='port for vrrp rpc interface') ]) self._args = args self._kwargs = kwargs self._peers = [] self._rpc_events = hub.Queue(128) self.server_thread = hub.spawn(self._peer_accept_thread) self.event_thread = hub.spawn(self._rpc_request_loop_thread)
def serve(self): send_thr = hub.spawn(self._send_loop) # send hello message immediately hello = self.ofproto_parser.OFPHello(self) self.send_msg(hello) echo_thr = hub.spawn(self._echo_request_loop) try: self._recv_loop() finally: hub.kill(send_thr) hub.kill(echo_thr) hub.joinall([send_thr, echo_thr]) self.is_active = False
def _create_bgp_speaker_for_vlan(self, bgp_speaker_key, bgp_router): """Set up BGP speaker for an individual VLAN if required. Args: bgp_speaker_key (BgpSpeakerKey): BGP speaker key. bgp_router: Router. Returns: ryu.services.protocols.bgp.bgpspeaker.BGPSpeaker: BGP speaker. """ server_address = sorted( bgp_router.bgp_server_addresses_by_ipv(bgp_speaker_key.ipv))[0] beka = Beka(local_address=str(server_address), bgp_port=bgp_router.bgp_port(), local_as=bgp_router.bgp_as(), router_id=bgp_router.bgp_routerid(), peer_up_handler=self._bgp_up_handler, peer_down_handler=self._bgp_down_handler, route_handler=lambda x: self._bgp_route_handler( x, bgp_speaker_key), error_handler=self.logger.warning) for ip_dst, ip_gw in self._vlan_prefixes_by_ipv( bgp_router.bgp_vlan(), bgp_speaker_key.ipv): beka.add_route(prefix=str(ip_dst), next_hop=str(ip_gw)) for bgp_neighbor_address in bgp_router.bgp_neighbor_addresses_by_ipv( bgp_speaker_key.ipv): beka.add_neighbor(connect_mode=bgp_router.bgp_connect_mode(), peer_ip=str(bgp_neighbor_address), peer_as=bgp_router.bgp_neighbor_as()) self.thread = hub.spawn(beka.run) self.thread.name = 'beka' return beka
def start(self): super(ZServer, self).start() if self.zapi_connection_family == socket.AF_UNIX: unix_sock_dir = os.path.dirname(CONF.server_host) # Makes sure the unix socket does not already exist if os.path.exists(CONF.server_host): os.remove(CONF.server_host) if not os.path.isdir(unix_sock_dir): os.mkdir(unix_sock_dir) os.chmod(unix_sock_dir, 0o777) try: self.zserv = hub.StreamServer(self.zserv_addr, zclient_connection_factory) except OSError as e: self.logger.error('Cannot start Zebra server%s: %s', self.zserv_addr, e) raise e if self.zapi_connection_family == socket.AF_UNIX: os.chmod(CONF.server_host, 0o777) self._add_lo_interface() return hub.spawn(self.zserv.serve_forever)
def start(self): if ip.valid_ipv6(self._address): server = hub.listen((self._address, self._port), family=socket.AF_INET6) else: server = hub.listen((self._address, self._port)) key = self.CONF.ovsdb.mngr_privkey or self.CONF.ctl_privkey cert = self.CONF.ovsdb.mngr_cert or self.CONF.ctl_cert if key is not None and cert is not None: ssl_kwargs = dict(keyfile=key, certfile=cert, server_side=True) if self.CONF.ca_certs is not None: ssl_kwargs['cert_reqs'] = ssl.CERT_REQUIRED ssl_kwargs['ca_certs'] = self.CONF.ca_certs server = ssl.wrap_socket(server, **ssl_kwargs) self._server = server if ip.valid_ipv6(self._address): self.logger.info('Listening on [%s]:%s for clients', self._address, self._port) else: self.logger.info('Listening on %s:%s for clients', self._address, self._port) t = hub.spawn(self._accept, self._server) super(OVSDB, self).start() return t
def start(self, prom_port, prom_addr, use_test_thread=False): """Start webserver.""" if not self.server: app = make_wsgi_app(self._reg) if use_test_thread: # pylint: disable=import-outside-toplevel from wsgiref.simple_server import (make_server, WSGIRequestHandler) import threading class NoLoggingWSGIRequestHandler(WSGIRequestHandler): """Don't log requests.""" def log_message(self, format, *args): # pylint: disable=redefined-builtin pass self.server = make_server( prom_addr, int(prom_port), app, handler_class=NoLoggingWSGIRequestHandler) self.thread = threading.Thread( target=self.server.serve_forever) self.thread.daemon = True self.thread.start() else: self.server = hub.WSGIServer((prom_addr, int(prom_port)), app) self.thread = hub.spawn(self.server.serve_forever) self.thread.name = 'prometheus'
def test_ssl(self): """Tests SSL server functionality.""" # TODO: TLS version enforcement is necessary to avoid # vulnerable versions. Currently, this only tests TLS # connectivity. this_dir = os.path.dirname(sys.modules[__name__].__file__) saved_exception = None try: ssl_version = ssl.PROTOCOL_TLS except AttributeError: # For compatibility with older pythons. ssl_version = ssl.PROTOCOL_TLSv1 for i in range(3): try: # Try a few times as this can fail with EADDRINUSE port = random.randint(5000, 10000) server = hub.spawn(self._test_ssl, this_dir, port) hub.sleep(1) client = hub.StreamClient(("127.0.0.1", port), timeout=5, ssl_version=ssl_version) if client.connect() is not None: break except Exception as e: saved_exception = e continue finally: try: hub.kill(server) except Exception: pass else: self.fail("Failed to connect: " + str(saved_exception))
def start(self): """Start socket server.""" if self.socket_path: stream_server = StreamServer((self.socket_path, None), self._loop).serve_forever self.thread = hub.spawn(stream_server) self.thread.name = 'event' return self.thread
def start(self): super(BMPStation, self).start() self.logger.debug("listening on %s:%s", self.server_host, self.server_port) return hub.spawn( StreamServer((self.server_host, self.server_port), self.loop).serve_forever)
def __init__(self): super(OpenFlowController, self).__init__() if not CONF.ofp_tcp_listen_port and not CONF.ofp_ssl_listen_port: self.ofp_tcp_listen_port = ofproto_common.OFP_TCP_PORT self.ofp_ssl_listen_port = ofproto_common.OFP_SSL_PORT # For the backward compatibility, we spawn a server loop # listening on the old OpenFlow listen port 6633. hub.spawn(self.server_loop, ofproto_common.OFP_TCP_PORT_OLD, ofproto_common.OFP_SSL_PORT_OLD) else: self.ofp_tcp_listen_port = CONF.ofp_tcp_listen_port self.ofp_ssl_listen_port = CONF.ofp_ssl_listen_port # Example: # self._clients = { # ('127.0.0.1', 6653): <instance of StreamClient>, # } self._clients = {}
def start(**kwargs): """Starts new context using provided configuration. Raises RuntimeConfigError if a context is already active. """ if CORE_MANAGER.started: raise RuntimeConfigError('Current context has to be stopped to start ' 'a new context.') try: waiter = kwargs.pop('waiter') except KeyError: waiter = hub.Event() common_config = CommonConf(**kwargs) hub.spawn(CORE_MANAGER.start, *[], **{ 'common_conf': common_config, 'waiter': waiter }) return True
def __init__(self, *args, **kwargs): super(Switches, self).__init__(*args, **kwargs) self.name = 'switches' self.dps = {} # datapath_id => Datapath class self.port_state = {} # datapath_id => ports self.ports = PortDataState() # Port class -> PortData class self.links = LinkState() # Link class -> timestamp self.hosts = HostState() # mac address -> Host class list self.is_active = True self.link_discovery = self.CONF.observe_links if self.link_discovery: self.install_flow = self.CONF.install_lldp_flow self.explicit_drop = self.CONF.explicit_drop self.lldp_event = hub.Event() self.link_event = hub.Event() self.threads.append(hub.spawn(self.lldp_loop)) self.threads.append(hub.spawn(self.link_loop))
def start(self): """Start controller.""" super().start() if self.prom_client: self.logger.info('version %s', self.prom_client.version) if self.stat_reload: self.logger.info('will automatically reload new config on changes') self.reload_config(None) self.threads.extend( [hub.spawn(thread) for thread in (self._config_file_stat, )]) signal.signal(signal.SIGHUP, self.signal_handler) signal.signal(signal.SIGINT, self.signal_handler)
def _spawn_activity(self, activity, *args, **kwargs): """Starts *activity* in a new thread and passes *args* and *kwargs*. Maintains pointer to this activity and stops *activity* when this activity is stopped. """ self._validate_activity(activity) # Spawn a new greenthread for given activity greenthread = hub.spawn(activity.start, *args, **kwargs) self._child_thread_map[activity.name] = greenthread self._child_activity_map[activity.name] = activity return greenthread
def start(self): self.is_active = True try: self.sock = create_connection(self.client.zserv_addr) except socket.error as e: self.logger.exception('Cannot connect to Zebra server%s: %s', self.client.zserv_addr, e) self.stop() return None self.sock.settimeout(GLOBAL_CONF.socket_timeout) self.threads.append(hub.spawn(self._send_loop)) self.threads.append(hub.spawn(self._recv_loop)) # Send the following messages at starting connection. # - ZEBRA_HELLO to register route_type # - ZEBRA_ROUTER_ID_ADD to get router_id # - ZEBRA_INTERFACE_ADD to get info for interfaces self.client.send_msg( zebra.ZebraMessage(version=self.client.zserv_ver, body=zebra.ZebraHello( route_type=self.client.route_type, instance=0))) self.client.send_msg( zebra.ZebraMessage(version=self.client.zserv_ver, body=zebra.ZebraRouterIDAdd())) self.client.send_msg( zebra.ZebraMessage(version=self.client.zserv_ver, body=zebra.ZebraInterfaceAdd())) self.client.send_event_to_observers( zclient_event.EventZServConnected(self)) hub.joinall(self.threads) self.client.send_event_to_observers( zclient_event.EventZServDisconnected(self))
def _do_query(self, query, iph, eth, in_port, msg): """the process when the snooper received a QUERY message.""" datapath = msg.datapath dpid = datapath.id ofproto = datapath.ofproto parser = datapath.ofproto_parser # learn the querier. self._to_querier[dpid] = { 'port': in_port, 'ip': iph.src, 'mac': eth.src } # set the timeout time. timeout = igmp.QUERY_RESPONSE_INTERVAL if query.maxresp: timeout = query.maxresp / 10 self._to_hosts.setdefault(dpid, {}) if query.address == '0.0.0.0': # general query. reset all reply status. for group in self._to_hosts[dpid].values(): group['replied'] = False group['leave'] = None else: # specific query. reset the reply status of the specific # group. group = self._to_hosts[dpid].get(query.address) if group: group['replied'] = False group['leave'] = None actions = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)] self._do_packet_out(datapath, msg.data, in_port, actions) # wait for REPORT messages. hub.spawn(self._do_timeout_for_query, timeout, datapath)
def start(self): # Start os-ken event loop thread super(OVSNeutronAgentOSKenApp, self).start() def _make_br_cls(br_cls): return functools.partial(br_cls, os_ken_app=self) # Start agent main loop thread bridge_classes = { 'br_int': _make_br_cls(br_int.OVSIntegrationBridge), 'br_phys': _make_br_cls(br_phys.OVSPhysicalBridge), 'br_tun': _make_br_cls(br_tun.OVSTunnelBridge), } return hub.spawn(agent_main_wrapper, bridge_classes, raise_error=True)
def start(self): super(OSKenBGPSpeaker, self).start() # If configuration file was provided and loaded successfully, we start # BGPSpeaker using the given settings. # If no configuration file is provided or if any minimum required # setting is missing, BGPSpeaker will not be started. if self.config_file: LOG.debug('Loading config file %s...', self.config_file) settings = load_config(self.config_file) # Configure logging settings, if available. if hasattr(settings, 'LOGGING'): # Not implemented yet. LOG.debug('Loading LOGGING settings... (NOT implemented yet)') # from logging.config import dictConfig # logging_settings = dictConfig(settings.LOGGING) # Configure BGP settings, if available. if hasattr(settings, 'BGP'): LOG.debug('Loading BGP settings...') self._start_speaker(settings.BGP) # Configure SSH settings, if available. if hasattr(settings, 'SSH'): LOG.debug('Loading SSH settings...') # Note: paramiko used in bgp.operator.ssh is the optional # requirements, imports bgp.operator.ssh here. from os_ken.services.protocols.bgp.operator import ssh hub.spawn(ssh.SSH_CLI_CONTROLLER.start, **settings.SSH) # Start RPC server with the given RPC settings. rpc_settings = { NC_RPC_BIND_PORT: CONF.rpc_port, NC_RPC_BIND_IP: validate_rpc_host(CONF.rpc_host), } return hub.spawn(NET_CONTROLLER.start, **rpc_settings)
def start(self): # discard received packets before joining multicast membership packet_socket = self.packet_socket packet_socket.setblocking(0) with hub.Timeout(0.1, False): while True: try: packet_socket.recv(1500) except socket.error: break packet_socket.setblocking(1) self._join_multicast_membership(True) self._join_vrrp_group(True) super(VRRPInterfaceMonitorNetworkDevice, self).start() self.threads.append(hub.spawn(self._recv_loop))