Пример #1
0
 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)
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
 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
Пример #5
0
 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
Пример #6
0
    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)