def test_basic(self): buf = OpenFlowBuffer() message = ofp_flow_mod(match=ofp_match(in_port=1, nw_src="1.1.1.1"), action=ofp_action_output(port=1)) mock_conn = MockConnection() buf.insert_pending_receipt(1, "c1", message, mock_conn) pending_receipt = PendingReceive(1, "c1", OFFingerprint.from_pkt(message)) self.assertTrue(buf.message_receipt_waiting(pending_receipt)) buf.schedule(pending_receipt) self.assertTrue(mock_conn.passed_message) self.assertFalse(buf.message_receipt_waiting(pending_receipt))
def __init__(self, dpid, name=None, ports=4, miss_send_len=128, n_buffers=100, n_tables=1, capabilities=None, can_connect_to_endhosts=True): NXSoftwareSwitch.__init__(self, dpid, name, ports, miss_send_len, n_buffers, n_tables, capabilities) # Whether this is a core or edge switch self.can_connect_to_endhosts = can_connect_to_endhosts self.create_connection = None self.failed = False self.log = logging.getLogger("FuzzSoftwareSwitch(%d)" % dpid) if logging.getLogger().getEffectiveLevel() <= logging.DEBUG: def _print_entry_remove(table_mod): if table_mod.removed != []: self.log.debug("Table entry removed %s" % str(table_mod.removed)) self.table.addListener(FlowTableModification, _print_entry_remove) def error_handler(e): self.log.exception(e) raise e self.cid2connection = {} self.error_handler = error_handler self.controller_info = [] # Tell our buffer to insert directly to our flow table whenever commands are let through by control_flow. self.delay_flow_mods = False self.openflow_buffer = OpenFlowBuffer() self.barrier_deque = None # Boolean representing whether to use randomize_flow_mod mode to prioritize the order in which flow_mods are processed. self.randomize_flow_mod_order = False # Uninitialized RNG (initialize through randomize_flow_mods()) self.random = None self.port_violations = []
def bootstrap(self, sync_callback, boot_controllers=default_boot_controllers): '''Return a simulation object encapsulating the state of the system in its initial starting point: - boots controllers - connects switches to controllers May be invoked multiple times! ''' def remove_monkey_patch(): if hasattr(select, "_old_select"): # Revert the previous monkeypatch to allow the new true_sockets to # connect select.select = select._old_select socket.socket = socket._old_socket def initialize_io_loop(): ''' boot the IOLoop (needed for the controllers) ''' _io_master = IOMaster() # monkey patch time.sleep for all our friends _io_master.monkey_time_sleep() # tell sts.console to use our io_master msg.set_io_master(_io_master) return _io_master def wire_controller_patch_panel(controller_manager, create_io_worker): patch_panel = None if not self.interpose_on_controllers: return patch_panel # N.B. includes local controllers in network namespaces or VMs. remote_controllers = controller_manager.remote_controllers if len(remote_controllers) != 0: patch_panel = self.controller_patch_panel_class( create_io_worker) for c in remote_controllers: patch_panel.register_controller(c.cid, c.guest_eth_addr, c.host_device) return patch_panel def instantiate_topology(create_io_worker): '''construct a clean topology object from topology_class and topology_params''' log.info("Creating topology...") # If you want to shoot yourself in the foot, feel free :) comma = "" if self._topology_params == "" else "," topology = eval( "%s(%s%screate_io_worker=create_io_worker)" % (self._topology_class.__name__, self._topology_params, comma)) return topology # Instantiate the pieces needed for Simulation's constructor remove_monkey_patch() io_master = initialize_io_loop() sync_connection_manager = STSSyncConnectionManager( io_master, sync_callback) controller_manager = boot_controllers(self.controller_configs, self.snapshot_service, sync_connection_manager) controller_patch_panel = wire_controller_patch_panel( controller_manager, io_master.create_worker_for_socket) topology = instantiate_topology(io_master.create_worker_for_socket) patch_panel = self._patch_panel_class(topology.switches, topology.hosts, topology.get_connected_port) openflow_buffer = OpenFlowBuffer() dataplane_trace = None if self._dataplane_trace_path is not None: dataplane_trace = Trace(self._dataplane_trace_path, topology) if self._violation_persistence_threshold is not None: violation_tracker = ViolationTracker( self._violation_persistence_threshold) else: violation_tracker = ViolationTracker() simulation = Simulation(topology, controller_manager, dataplane_trace, openflow_buffer, io_master, controller_patch_panel, patch_panel, sync_callback, self.multiplex_sockets, violation_tracker, self._kill_controllers_on_exit) self.current_simulation = simulation return simulation
def bootstrap(self, sync_callback=None, boot_controllers=default_boot_controllers): '''Return a simulation object encapsulating the state of the system in its initial starting point: - boots controllers - connects switches to controllers May be invoked multiple times! ''' if sync_callback is None: sync_callback = ReplaySyncCallback(None) def initialize_io_loop(): ''' boot the IOLoop (needed for the controllers) ''' _io_master = IOMaster() # monkey patch time.sleep for all our friends _io_master.monkey_time_sleep() # tell sts.console to use our io_master msg.set_io_master(_io_master) return _io_master def wire_controller_patch_panel(controller_manager, create_io_worker): patch_panel = None if not self.interpose_on_controllers: return patch_panel # N.B. includes local controllers in network namespaces or VMs. remote_controllers = controller_manager.remote_controllers if len(remote_controllers) != 0: patch_panel = self.controller_patch_panel_class(create_io_worker) for c in remote_controllers: patch_panel.register_controller(c.cid, c.guest_eth_addr, c.host_device) return patch_panel def instantiate_topology(create_io_worker): '''construct a clean topology object from topology_class and topology_params''' log.info("Creating topology...") # If you want to shoot yourself in the foot, feel free :) comma = "" if self._topology_params == "" else "," topology = eval("%s(%s%screate_io_worker=create_io_worker)" % (self._topology_class.__name__, self._topology_params, comma)) return topology def monkeypatch_select(multiplex_sockets, controller_manager): mux_select = None demuxers = [] if multiplex_sockets: log.debug("Monkeypatching STS select") revert_select_monkeypatch() # Monkey patch select to use our deterministic version mux_select = MultiplexedSelect() for c in controller_manager.controller_configs: # Connect the true sockets true_socket = connect_socket_with_backoff(address=c.address, port=c.port) true_socket.setblocking(0) io_worker = mux_select.create_worker_for_socket(true_socket) demux = STSSocketDemultiplexer(io_worker, c.server_info) demuxers.append(demux) # Monkey patch select.select select._old_select = select.select select.select = mux_select.select return (mux_select, demuxers) # Instantiate the pieces needed for Simulation's constructor revert_select_monkeypatch() io_master = initialize_io_loop() sync_connection_manager = STSSyncConnectionManager(io_master, sync_callback) controller_manager = boot_controllers(self.controller_configs, self.snapshot_service, sync_connection_manager, multiplex_sockets=self.multiplex_sockets) controller_patch_panel = wire_controller_patch_panel(controller_manager, io_master.create_worker_for_socket) topology = instantiate_topology(io_master.create_worker_for_socket) patch_panel = self._patch_panel_class(topology.switches, topology.hosts, topology.get_connected_port) openflow_buffer = OpenFlowBuffer() dataplane_trace = None if self._dataplane_trace_path is not None: dataplane_trace = Trace(self._dataplane_trace_path, topology) if self._violation_persistence_threshold is not None: violation_tracker = ViolationTracker(self._violation_persistence_threshold) else: violation_tracker = ViolationTracker() # Connect up MuxSelect if enabled (mux_select, demuxers) = monkeypatch_select(self.multiplex_sockets, controller_manager) simulation = Simulation(topology, controller_manager, dataplane_trace, openflow_buffer, io_master, controller_patch_panel, patch_panel, sync_callback, mux_select, demuxers, violation_tracker, self._kill_controllers_on_exit) if self.ignore_interposition: simulation.set_pass_through() self.current_simulation = simulation return simulation