def handle_packet_in(self, event): """Handle PacketIn Event. Install flows allowing communication between switch ports. Args: event (KytosPacketIn): Received Event """ log.debug("PacketIn Received") packet_in = event.content['message'] ethernet = Ethernet() ethernet.unpack(packet_in.data.value) # Ignore LLDP packets or packets not generated by table-miss flows if (ethernet.destination in settings.lldp_macs or packet_in.reason != PacketInReason.OFPR_NO_MATCH): return # Learn the port where the sender is connected in_port = packet_in.in_port.value switch = event.source.switch switch.update_mac_table(ethernet.source, in_port) ports = switch.where_is_mac(ethernet.destination) # Add a flow to the switch if the destination is known if ports: flow_mod = FlowMod() flow_mod.command = FlowModCommand.OFPFC_ADD flow_mod.match = Match() flow_mod.match.dl_src = ethernet.source.value flow_mod.match.dl_dst = ethernet.destination.value flow_mod.match.dl_type = ethernet.ether_type flow_mod.actions.append(ActionOutput(port=ports[0])) event_out = KytosEvent(name=('kytos/of_l2ls.messages.out.' 'ofpt_flow_mod'), content={ 'destination': event.source, 'message': flow_mod }) self.controller.buffers.msg_out.put(event_out) # Send the packet to correct destination or flood it packet_out = PacketOut() packet_out.buffer_id = packet_in.buffer_id packet_out.in_port = packet_in.in_port packet_out.data = packet_in.data port = ports[0] if ports else Port.OFPP_FLOOD packet_out.actions.append(ActionOutput(port=port)) event_out = KytosEvent(name=('kytos/of_l2ls.messages.out.' 'ofpt_packet_out'), content={ 'destination': event.source, 'message': packet_out }) self.controller.buffers.msg_out.put(event_out)
def as_flow_mod(self, flow_type=FlowModCommand.OFPFC_ADD): """Transform a Flow object into a flow_mod message. Args: flow_type (|flow_mod_command|): type of flow_mod to be converted. Returns: |flow_mod|: Instance of FlowMod with Flow attributes. """ flow_mod = FlowMod() flow_mod.command = flow_type flow_mod_attributes = [ 'buffer_id', 'idle_timeout', 'hard_timeout', 'priority' ] for attribute_name in flow_mod_attributes: value = getattr(self, attribute_name) if value is not None: setattr(flow_mod, attribute_name, value) flow_mod.match = Match() match_attributes = [ 'in_port', 'dl_src', 'dl_dst', 'dl_vlan', 'dl_type', 'nw_src', 'nw_dst', 'tp_dst' ] for attribute_name in match_attributes: value = getattr(self, attribute_name) if value is not None: setattr(flow_mod.match, attribute_name, value) if self.actions is not None: for action in self.actions: flow_mod.actions.append(action.as_of_action()) return flow_mod
def ipv6_drop(self, event): """Install a flow on the switch that drop all incoming ipv6 packets.""" switch = event.content['switch'] if switch.connection.protocol.version is not 0x01: return flow_mod = FlowMod() flow_mod.command = FlowModCommand.OFPFC_ADD flow_mod.match = Match() flow_mod.match.dl_type = 0x86dd # ipv6 event_out = KytosEvent(name=('kytos/of_ipv6drop.messages.out.' 'ofpt_flow_mod'), content={'destination': switch.connection, 'message': flow_mod}) log.info('Sending "IPv6 DROP" flow to switch %s', switch.id) self.controller.buffers.msg_out.put(event_out)
def from_dict(self, dictionary): """Return an OF 1.0 FlowMod message from serialized dictionary.""" flow_mod = FlowMod() for field, data in dictionary.items(): if field in self.flow_attributes: setattr(flow_mod, field, data) elif field == 'match': self._update_match(flow_mod.match, data) elif field == 'actions': actions = self._actions_from_list(data) flow_mod.actions.extend(actions) return flow_mod
def generate_flow_mod_message(self, xid, srcIpAddress): match = Match(dl_type=2048, nw_src=IPAddress(srcIpAddress)) message = FlowMod(xid=xid, match=match, command=FlowModCommand.OFPFC_ADD) return message.pack()