def tracepath(self): """ Do the trace path The logic is very simple: 1 - Generate the probe packet using entries provided 2 - Results a result and the packet_in (used to generate new probe) Possible results: 'timeout' meaning the end of trace or the trace step {'dpid', 'port'} Some networks do vlan rewriting, so it is important to get the packetIn msg with the header 3 - If result is a trace step, send PacketOut to the switch that originated the PacketIn. Repeat till reaching timeout """ log.warning("Starting Trace Path ID: %s" % self.id) entries = copy.deepcopy(self.init_entries) color = Colors().get_switch_color(self.init_switch.dpid) switch = self.init_switch # Add initial trace step self.rest.add_trace_step(self.trace_result, trace_type='starting', dpid=switch.dpid, port=entries.in_port) # A loop waiting for 'trace_ended'. # It changes to True when reaches timeout self.tracepath_loop(entries, color, switch) # Add final result to trace_results_queue t_result = {"request_id": self.id, "result": self.trace_result, "start_time": str(self.rest.start_time), "total_time": self.rest.get_time(), "request": self.init_entries.init_entries} self.trace_mgr.add_result(self.id, t_result)
def tracepath_loop(self, entries, color, switch): """ This method sends the packet_out per hop, create the result to be posted via REST. """ # A loop waiting for 'trace_ended'. # It changes to True when reaches timeout while not self.trace_ended: in_port, probe_pkt = generate_trace_pkt(entries, color, self.id) result, packet_in = self.send_trace_probe(switch, in_port, probe_pkt) if result == 'timeout': self.rest.add_trace_step(self.trace_result, trace_type='last') log.warning("Trace %s: Trace Completed!" % self.id) self.trace_ended = True else: self.rest.add_trace_step(self.trace_result, trace_type='trace', dpid=result['dpid'], port=result['port']) if self.check_loop(): self.rest.add_trace_step(self.trace_result, trace_type='last', reason='loop') self.trace_ended = True break # If we got here, that means we need to keep going. entries, color, switch = prepare_next_packet(entries, result, packet_in)
def tracepath(self): """ Do the trace path The logic is very simple: 1 - Generate the probe packet using entries provided 2 - Results a result and the packet_in (used to generate new probe) Possible results: 'timeout' meaning the end of trace or the trace step {'dpid', 'port'} Some networks do vlan rewriting, so it is important to get the packetIn msg with the header 3 - If result is a trace step, send PacketOut to the switch that originated the PacketIn. Repeat till reaching timeout """ log.warning("Starting Trace Path for ID %s" % self.id) entries = copy.deepcopy(self.init_entries) color = Colors().get_switch_color(self.init_switch.dpid) switch = self.init_switch # Add initial trace step self.rest.add_trace_step(self.trace_result, trace_type='starting', dpid=switch.dpid, port=entries['trace']['switch']['in_port']) # A loop waiting for 'trace_ended'. It changes to True when reaches timeout while not self.trace_ended: in_port, probe_pkt = generate_trace_pkt(entries, color, self.id, self.mydomain) result, packet_in = self.send_trace_probe(switch, in_port, probe_pkt) if result == 'timeout': self.rest.add_trace_step(self.trace_result, trace_type='last') log.warning("Intra-Domain Trace Completed!") self.trace_ended = True else: self.rest.add_trace_step(self.trace_result, trace_type='trace', dpid=result['dpid'], port=result['port']) if self.check_loop(): self.rest.add_trace_step(self.trace_result, trace_type='last', reason='loop') self.trace_ended = True break # If we got here, that means we need to keep going. entries, color, switch = prepare_next_packet( entries, result, packet_in) # Add final result to trace_results_queue t_result = { "request_id": self.id, "result": self.trace_result, "start_time": str(self.rest.start_time), "total_time": self.rest.get_time(), "request": self.init_entries } self.trace_mgr.add_result(self.id, t_result)
def name(self): """Return name from Box instance. Returns: string: Box name. """ log.warning("The name parameter will be deprecated soon.") return self._name
def _add_utilization(self, row, iface): """Calculate utilization and also add port number.""" speed = row['speed'] if speed is None: for util_col in self._util_cols.values(): row[util_col] = None log.warning('No speed, port %s, dpid %s', self._port, self._dpid[-3:]) else: for bytes_col, util_col in self._util_cols.items(): row[util_col] = row[bytes_col] / (speed / 8) # bytes/sec return row
def check_loop(self): """ Check if there are equal entries Return: True if loop 0 if not """ last = self.trace_result[-1] for result in self.trace_result[:-1]: if result['dpid'] == last['dpid']: if result['port'] == last['port']: log.warning('Trace %s: Loop Detected on %s port %s!!' % (self.id, last['dpid'], last['port'])) return True return 0
def _add_utilization(self, row, iface): # pylint: disable=unused-argument """Calculate utilization and also add port number.""" speed = row['speed'] if speed is None: for util_col in self._util_cols.values(): row[util_col] = None # Shorten dpid for better log readability if len(self._dpid) >= 22: dpid = self._dpid[:3] + '...' + self._dpid[-3:] else: dpid = self._dpid log.warning('No speed, port %s, dpid %s', self._port, dpid) else: for bytes_col, util_col in self._util_cols.items(): row[util_col] = row[bytes_col] / speed # bytes/sec return row
def send_trace_probe(self, switch, in_port, probe_pkt): """ This method sends the PacketOut and checks if the PacketIn was received in 3 seconds. Args: switch: target switch to start with in_port: target port to start with probe_pkt: ethernet frame to send (PacketOut.data) Returns: Timeout {switch & port} """ timeout_control = 0 # Controls the timeout of 1 second and two tries while True: log.warning('Trace %s: Sending POut to switch: %s and in_port %s ' % (self.id, switch.dpid, in_port)) send_packet_out(self.trace_mgr.controller, switch, in_port, probe_pkt) time.sleep(0.5) # Wait 0.5 second before querying for PacketIns timeout_control += 1 if timeout_control >= 3: return 'timeout', False # Check if there is any Probe PacketIn in the queue for pkt_in_msg in self.trace_mgr.trace_pkt_in: # Let's look for traces with our self.id # Each entry has the following format: # {"dpid": pkt_in_dpid, "in_port": pkt_in_port, # "msg": msg, "ethernet": ethernet, "event": event} # packetIn_data_request_id is the request id # of the packetIn.data. msg = pkt_in_msg["msg"] if self.id == msg.request_id: self.clear_trace_pkt_in() result = {"dpid": pkt_in_msg["dpid"], "port": pkt_in_msg["in_port"]} return result, pkt_in_msg["event"] else: log.warning('Trace %s: Sending PacketOut Again' % self.id) send_packet_out(self.trace_mgr.controller, switch, in_port, probe_pkt)
def fail_negotiation(self, connection, hello_message): """Send Error message and emit event upon negotiation failure.""" log.warning('connection %s: version negotiation failed', connection.id) connection.protocol.state = 'hello_failed' event_raw = KytosEvent(name='kytos/of_core.hello_failed', content={'source': connection}) self.controller.buffers.app.put(event_raw) version = max(settings.OPENFLOW_VERSIONS) pyof_lib = PYOF_VERSION_LIBS[version] error_message = pyof_lib.asynchronous.error_msg.ErrorMsg( xid=hello_message.header.xid, error_type=pyof_lib.asynchronous.error_msg.ErrorType. OFPET_HELLO_FAILED, code=pyof_lib.asynchronous.error_msg.HelloFailedCode. OFPHFC_INCOMPATIBLE) self.emit_message_out(connection, error_message)
def send_trace_probe(self, switch, in_port, probe_pkt): """ This method sends the PacketOut and checks if the PacketIn was received in 3 seconds. Args: switch: target switch to start with in_port: target port to start with probe_pkt: ethernet frame to send (PacketOut.data) Returns: Timeout {switch & port} """ timeout_control = 0 # Controls the timeout of 1 second and two tries log.warning('Tracer: Sending POut to switch: %s and in_port %s ' % (switch.dpid, in_port)) # send_packet_out(self.trace_mgr.controller, switch, in_port, probe_pkt.data) send_packet_out(self.trace_mgr.controller, switch, in_port, probe_pkt) while True: time.sleep(0.5) # Wait 0.5 second before querying for PacketIns timeout_control += 1 if timeout_control >= 3: return 'timeout', False # Check if there is any Probe PacketIn in the queue for pIn in self.trace_mgr.trace_pktIn: # Let's look for traces with our self.id # Each entry has the following format: # (pktIn_dpid, pktIn_port, TraceMsg, pkt, ev) # packetIn_data_request_id is the request id # of the packetIn.data. msg = pIn[2] if self.id == msg.request_id: self.clear_trace_pkt_in() return {'dpid': pIn[0], "port": pIn[1]}, pIn[4] else: log.warning('Sending PacketOut Again') # send_packet_out(self.trace_mgr.controller, switch, in_port, probe_pkt.data) send_packet_out(self.trace_mgr.controller, switch, in_port, probe_pkt)
def new_trace(self, entries): """Receives external requests for traces. Args: entries: user's options for trace Returns: int with the request/trace id """ is_valid, msg = self.is_entry_valid(entries) if not is_valid: log.warning(msg) return msg if self.verify_active_new_request(entries): msg = 'Ignoring Duplicated Trace Request Received' log.warn(msg) return msg trace_id = self.get_id() # Add to active_trace queue: self.add_to_active_traces(trace_id) # Add to request_queue self._request_queue[trace_id] = entries return trace_id
def name(self, value): log.warning("The name parameter will be deprecated soon.") self._name = value
def name(self): log.warning("The name parameter will be deprecated soon.") return self._name
def _get_switch(self): switch = self.controller.get_switch_by_dpid(self._dpid) if switch is None: log.warning('Switch %s not found in controller', self._dpid[-3:]) return switch
def name(self, value): log.warning("The name parameter will be deprecated soon.") self._name = value # pylint: disable=attribute-defined-outside-init