def as_of_action(self): """Return a pyof ActionSetField instance.""" tlv = OxmTLV() tlv.oxm_field = OxmOfbMatchField.OFPXMT_OFB_VLAN_VID oxm_value = self.vlan_id | VlanId.OFPVID_PRESENT tlv.oxm_value = oxm_value.to_bytes(2, 'big') return OFActionSetField(field=tlv)
def _build_lldp_flow_mod(self, version): """Build a FlodMod message to send LLDP to the controller. Args: version (int): OpenFlow version. Returns: FlowMod message for the specific given OpenFlow version, if it is supported. None if the OpenFlow version is not supported. """ if version == 0x01: flow_mod = FM10() flow_mod.command = FMC.OFPFC_ADD flow_mod.priority = settings.FLOW_PRIORITY flow_mod.match.dl_type = EtherType.LLDP if self.vlan_id: flow_mod.match.dl_vlan = self.vlan_id flow_mod.actions.append(AO10(port=Port10.OFPP_CONTROLLER)) elif version == 0x04: flow_mod = FM13() flow_mod.command = FMC.OFPFC_ADD flow_mod.priority = settings.FLOW_PRIORITY match_lldp = OxmTLV() match_lldp.oxm_field = OxmOfbMatchField.OFPXMT_OFB_ETH_TYPE match_lldp.oxm_value = EtherType.LLDP.to_bytes(2, 'big') flow_mod.match.oxm_match_fields.append(match_lldp) if self.vlan_id: match_vlan = OxmTLV() match_vlan.oxm_field = OxmOfbMatchField.OFPXMT_OFB_VLAN_VID vlan_value = self.vlan_id | VlanId.OFPVID_PRESENT match_vlan.oxm_value = vlan_value.to_bytes(2, 'big') flow_mod.match.oxm_match_fields.append(match_vlan) instruction = InstructionApplyAction() instruction.actions.append(AO13(port=Port13.OFPP_CONTROLLER)) flow_mod.instructions.append(instruction) else: flow_mod = None return flow_mod
def _create_flow_mod(version, packet, port): """Create a FlowMod message with the appropriate version and data.""" if version == '0x01': flow_mod = FlowMod10() flow_mod.match.dl_src = packet.source.value flow_mod.match.dl_dst = packet.destination.value flow_mod.match.dl_type = packet.ether_type flow_mod.actions.append(Output10(port=port)) else: flow_mod = FlowMod13() match_dl_type = OxmTLV() match_dl_type.oxm_field = OxmOfbMatchField.OFPXMT_OFB_ETH_TYPE match_dl_type.oxm_value = packet.ether_type.value.to_bytes( 2, 'big') flow_mod.match.oxm_match_fields.append(match_dl_type) match_dl_src = OxmTLV() match_dl_src.oxm_field = OxmOfbMatchField.OFPXMT_OFB_ETH_SRC match_dl_src.oxm_value = packet.source.pack() flow_mod.match.oxm_match_fields.append(match_dl_src) match_dl_dst = OxmTLV() match_dl_dst.oxm_field = OxmOfbMatchField.OFPXMT_OFB_ETH_DST match_dl_dst.oxm_value = packet.destination.pack() flow_mod.match.oxm_match_fields.append(match_dl_dst) action = Output13(port=port) instruction = InstructionApplyAction() instruction.actions.append(action) flow_mod.instructions.append(instruction) flow_mod.command = FlowModCommand.OFPFC_ADD flow_mod.priority = settings.FLOW_PRIORITY return flow_mod
def _match_from_dict(self, dictionary): known_fields = ((field, data) for field, data in dictionary.items() if field in self._match_names) for field_name, data in known_fields: tlv = OxmTLV() tlv.oxm_field = self._match_names[field_name] # set oxm_value if field_name in ('dl_vlan_pcp', 'nw_proto'): tlv.oxm_value = data.to_bytes(1, 'big') elif field_name == 'dl_vlan': vid = data | VlanId.OFPVID_PRESENT tlv.oxm_value = vid.to_bytes(2, 'big') elif field_name in ('dl_src', 'dl_dst'): tlv.oxm_value = HWAddress(data).pack() elif field_name in ('nw_src', 'nw_dst'): tlv.oxm_value = IPAddress(data).pack() elif field_name == 'in_port': tlv.oxm_value = data.to_bytes(4, 'big') else: tlv.oxm_value = data.to_bytes(2, 'big') yield tlv
def _create_vlan_tlv(vlan_id): tlv = OxmTLV() tlv.oxm_field = OxmOfbMatchField.OFPXMT_OFB_VLAN_VID oxm_value = vlan_id | VlanId.OFPVID_PRESENT tlv.oxm_value = oxm_value.to_bytes(2, 'big') return tlv
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 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.priority = settings.flow_priority match_dl_type = OxmTLV() match_dl_type.oxm_field = OxmOfbMatchField.OFPXMT_OFB_ETH_TYPE match_dl_type.oxm_value = ethernet.ether_type.value.to_bytes( 2, 'big') flow_mod.match.oxm_match_fields.append(match_dl_type) match_dl_src = OxmTLV() match_dl_src.oxm_field = OxmOfbMatchField.OFPXMT_OFB_ETH_SRC match_dl_src.oxm_value = ethernet.source.pack() flow_mod.match.oxm_match_fields.append(match_dl_src) match_dl_dst = OxmTLV() match_dl_dst.oxm_field = OxmOfbMatchField.OFPXMT_OFB_ETH_DST match_dl_dst.oxm_value = ethernet.destination.pack() flow_mod.match.oxm_match_fields.append(match_dl_dst) action = ActionOutput(port=ports[0]) instruction = InstructionApplyAction() instruction.actions.append(action) flow_mod.instructions.append(instruction) 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 = in_port packet_out.data = packet_in.data port = ports[0] if ports else PortNo.OFPP_FLOOD out_action = ActionOutput(port=port) packet_out.actions.append(out_action) 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)