예제 #1
0
    def setUpClass(cls):
        """Setup TestStruct."""
        reason = FlowRemovedReason.OFPRR_IDLE_TIMEOUT
        match = Match(in_port=80,
                      dl_vlan=1,
                      dl_vlan_pcp=1,
                      dl_type=1,
                      nw_tos=1,
                      nw_proto=1,
                      tp_src=80,
                      tp_dst=80,
                      dl_src=HWAddress('00:00:00:00:00:00'),
                      dl_dst=HWAddress('00:00:00:00:00:00'),
                      nw_src=IPAddress('192.168.0.1'),
                      nw_dst=IPAddress('192.168.0.2'))

        super().setUpClass()
        super().set_raw_dump_file('v0x01', 'ofpt_flow_removed')
        super().set_raw_dump_object(FlowRemoved,
                                    xid=12,
                                    match=match,
                                    cookie=0,
                                    priority=1,
                                    reason=reason,
                                    duration_sec=4,
                                    duration_nsec=23,
                                    idle_timeout=9,
                                    packet_count=10,
                                    byte_count=4)
        super().set_minimum_size(88)
예제 #2
0
    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
예제 #3
0
class FlowStatsRequest(GenericStruct):
    """Body for ofp_stats_request of type OFPST_FLOW."""

    match = Match()
    table_id = UBInt8()
    #: Align to 32 bits.
    pad = Pad(1)
    out_port = UBInt16()

    def __init__(self, match=None, table_id=0xff, out_port=Port.OFPP_NONE):
        """Create a FlowStatsRequest with the optional parameters below.

        Args:
            match (:class:`~pyof.v0x01.common.flow_match.Match`):
                Fields to match.
            table_id (int): ID of table to read (from pyof_table_stats)
                0xff for all tables or 0xfe for emergency.
            out_port (:class:`int`, :class:`~pyof.v0x01.common.phy_port.Port`):
                Require matching entries to include this as an output port.
                A value of :attr:`.Port.OFPP_NONE` indicates no restriction.
        """
        super().__init__()
        self.match = Match() if match is None else match
        self.table_id = table_id
        self.out_port = out_port
예제 #4
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.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)
예제 #5
0
class FlowRemoved(GenericMessage):
    """Flow removed (datapath -> controller)."""

    #: :class:`~.header.Header`: OpenFlow Header
    header = Header(message_type=Type.OFPT_FLOW_REMOVED)
    #: :class:`~.flow_match.Match`: OpenFlow Header
    match = Match()
    cookie = UBInt64()

    priority = UBInt16()
    reason = UBInt8(enum_ref=FlowRemovedReason)
    #: Align to 32-bits.
    pad = Pad(1)

    duration_sec = UBInt32()
    duration_nsec = UBInt32()

    idle_timeout = UBInt16()
    #: Align to 64-bits.
    pad2 = Pad(2)
    packet_count = UBInt64()
    byte_count = UBInt64()

    def __init__(self,
                 xid=None,
                 match=None,
                 cookie=None,
                 priority=None,
                 reason=None,
                 duration_sec=None,
                 duration_nsec=None,
                 idle_timeout=None,
                 packet_count=None,
                 byte_count=None):
        """Assign parameters to object attributes.

        Args:
            xid (int): OpenFlow Header's xid.
            match (Match): Fields' description.
            cookie (int): Opaque controller-issued identifier.
            priority (int): Priority level of flow entry.
            reason (FlowRemovedReason): Why the flow was removed.
            duration_sec (int): Time the flow was alive in seconds.
            duration_nsec (int): Time the flow was alive in nanoseconds in
                addition to duration_sec.
            idle_timeout (int): Idle timeout from original flow mod.
            packet_count (int): Number of packets.
            byte_count (int): Byte count.
        """
        super().__init__(xid)
        self.match = match
        self.cookie = cookie
        self.priority = priority
        self.reason = reason
        self.duration_sec = duration_sec
        self.duration_nsec = duration_nsec
        self.idle_timeout = idle_timeout
        self.packet_count = packet_count
        self.byte_count = byte_count
def _get_match():
    """Function used to built Match instance used by AggregateStatsRequest."""
    return Match(in_port=80, dl_src="01:02:03:04:05:06",
                 dl_dst="01:02:03:04:05:06", dl_vlan=1,
                 dl_vlan_pcp=1, dl_type=1,
                 nw_tos=1, nw_proto=1,
                 nw_src='192.168.0.1', nw_dst='192.168.0.1',
                 tp_src=80, tp_dst=80)
예제 #7
0
def _get_match():
    """Function used to return a Match instance."""
    return Match(in_port=80, dl_src='01:02:03:04:05:06',
                 dl_dst='01:02:03:04:05:06', dl_vlan=1,
                 dl_vlan_pcp=1, dl_type=1,
                 nw_tos=1, nw_proto=1,
                 nw_src='192.168.0.1', nw_dst='192.168.0.1',
                 tp_src=80, tp_dst=80)
class FlowMod(GenericMessage):
    """Modifies the flow table from the controller."""

    header = Header(message_type=Type.OFPT_FLOW_MOD)
    match = Match()
    cookie = UBInt64()
    command = UBInt16(enum_ref=FlowModCommand)
    idle_timeout = UBInt16()
    hard_timeout = UBInt16()
    priority = UBInt16()
    buffer_id = UBInt32()
    out_port = UBInt16(enum_ref=Port)
    flags = UBInt16(enum_ref=FlowModFlags)
    actions = ListOfActions()

    def __init__(self,
                 xid=None,
                 match=None,
                 cookie=0,
                 command=None,
                 idle_timeout=0,
                 hard_timeout=0,
                 priority=0,
                 buffer_id=NO_BUFFER,
                 out_port=Port.OFPP_NONE,
                 flags=FlowModFlags.OFPFF_CHECK_OVERLAP,
                 actions=None):
        """The constructor just assings parameters to object attributes.

        Args:
            xid (int): xid to be used on the message header.
            match (Match): Fields to match.
            cookie (int): Opaque controller-issued identifier.
            command (FlowModCommand): One of OFPFC_*.
            idle_timeout (int): Idle time before discarding (seconds).
            hard_timeout (int): Max time before discarding (seconds).
            priority (int): Priority level of flow entry.
            buffer_idle (int): Buffered packet to apply to (or -1).
                Not meaningful for OFPFC_DELETE*.
            out_port (Port): For OFPFC_DELETE* commands, require matching
                entries to include this as an output port.
                A value of OFPP_NONE indicates no restriction.
            flags (FlowModFlags): One of OFPFF_*.
            actions (ListOfActions): The action length is inferred from the
                length field in the header.
        """
        super().__init__(xid)
        self.match = match
        self.cookie = cookie
        self.command = command
        self.idle_timeout = idle_timeout
        self.hard_timeout = hard_timeout
        self.priority = priority
        self.buffer_id = buffer_id
        self.out_port = out_port
        self.flags = flags
        self.actions = [] if actions is None else actions
예제 #9
0
    def __init__(self, match=Match(), table_id=0xff, out_port=Port.OFPP_NONE):
        """The constructor just assings parameters to object attributes.

        Args:
            match (Match): Fields to match.
            table_id (int): ID of table to read (from pyof_table_stats) 0xff
                for all tables or 0xfe for emergency.
            out_port (int): Require matching entries to include this as an
                output port. A value of OFPP_NONE indicates no restriction.
        """
        super().__init__()
        self.match = match
        self.table_id = table_id
        self.out_port = out_port
예제 #10
0
    def __init__(self, match=Match(), table_id=0xff, out_port=Port.OFPP_NONE):
        """Create a AggregateStatsRequest with the optional parameters below.

        Args:
            match (~pyof.v0x01.common.flow_match.Match): Fields to match.
            table_id (int): ID of table to read (from pyof_table_stats) 0xff
                for all tables or 0xfe for emergency.
            out_port (int): Require matching entries to include this as an
                output port. A value of OFPP_NONE indicates no restriction.
        """
        super().__init__()
        self.match = match
        self.table_id = table_id
        self.out_port = out_port
예제 #11
0
    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)
예제 #12
0
    def __init__(self,
                 xid=None,
                 match=None,
                 cookie=0,
                 command=None,
                 idle_timeout=0,
                 hard_timeout=0,
                 priority=0,
                 buffer_id=NO_BUFFER,
                 out_port=Port.OFPP_NONE,
                 flags=FlowModFlags.OFPFF_SEND_FLOW_REM,
                 actions=None):
        """Create a FlowMod with the optional parameters below.

        Args:
            xid (int): xid to be used on the message header.
            match (~pyof.v0x01.common.flow_match.Match): Fields to match.
            cookie (int): Opaque controller-issued identifier.
            command (~pyof.v0x01.controller2switch.flow_mod.FlowModCommand):
                One of OFPFC_*.
            idle_timeout (int): Idle time before discarding (seconds).
            hard_timeout (int): Max time before discarding (seconds).
            priority (int): Priority level of flow entry.
            buffer_idle (int): Buffered packet to apply to (or -1).
                Not meaningful for OFPFC_DELETE*.
            out_port (~pyof.v0x01.common.phy_port.Port):
                For OFPFC_DELETE* commands, require matching entries to include
                this as an output port. A value of OFPP_NONE indicates no
                restriction.
            flags (~pyof.v0x01.controller2switch.flow_mod.FlowModFlags):
                One of OFPFF_*.
            actions (~pyof.v0x01.common.action.ListOfActions):
                The action length is inferred from the length field in the
                header.
        """
        super().__init__(xid)
        self.match = match or Match()
        self.cookie = cookie
        self.command = command
        self.idle_timeout = idle_timeout
        self.hard_timeout = hard_timeout
        self.priority = priority
        self.buffer_id = buffer_id
        self.out_port = out_port
        self.flags = flags
        self.actions = actions or []
예제 #13
0
class AggregateStatsRequest(GenericStruct):
    """Body for ofp_stats_request of type OFPST_AGGREGATE."""

    match = Match()
    table_id = UBInt8()
    #: Align to 32 bits
    pad = Pad(1)
    out_port = UBInt16()

    def __init__(self, match=Match(), table_id=0xff, out_port=Port.OFPP_NONE):
        """Create a AggregateStatsRequest with the optional parameters below.

        Args:
            match (~pyof.v0x01.common.flow_match.Match): Fields to match.
            table_id (int): ID of table to read (from pyof_table_stats) 0xff
                for all tables or 0xfe for emergency.
            out_port (int): Require matching entries to include this as an
                output port. A value of OFPP_NONE indicates no restriction.
        """
        super().__init__()
        self.match = match
        self.table_id = table_id
        self.out_port = out_port
예제 #14
0
class FlowStatsRequest(GenericStruct):
    """Body for ofp_stats_request of type OFPST_FLOW."""

    match = Match()
    table_id = UBInt8()
    #: Align to 32 bits.
    pad = Pad(1)
    out_port = UBInt16()

    def __init__(self, match=Match(), table_id=0xff, out_port=Port.OFPP_NONE):
        """The constructor just assings parameters to object attributes.

        Args:
            match (Match): Fields to match.
            table_id (int): ID of table to read (from pyof_table_stats)
                0xff for all tables or 0xfe for emergency.
            out_port (:class:`int`, :class:`.Port`): Require matching entries
                to include this as an output port. A value of
                :attr:`.Port.OFPP_NONE` indicates no restriction.
        """
        super().__init__()
        self.match = match
        self.table_id = table_id
        self.out_port = out_port
예제 #15
0
def _get_match():
    """Return a Match object."""
    return Match()
예제 #16
0
 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()
예제 #17
0
class FlowStats(GenericStruct):
    """Body of reply to OFPST_FLOW request."""

    length = UBInt16()
    table_id = UBInt8()
    #: Align to 32 bits.
    pad = Pad(1)
    match = Match()
    duration_sec = UBInt32()
    duration_nsec = UBInt32()
    priority = UBInt16()
    idle_timeout = UBInt16()
    hard_timeout = UBInt16()
    #: Align to 64-bits
    pad2 = Pad(6)
    cookie = UBInt64()
    packet_count = UBInt64()
    byte_count = UBInt64()
    actions = ListOfActions()

    def __init__(self,
                 length=None,
                 table_id=None,
                 match=None,
                 duration_sec=None,
                 duration_nsec=None,
                 priority=None,
                 idle_timeout=None,
                 hard_timeout=None,
                 cookie=None,
                 packet_count=None,
                 byte_count=None,
                 actions=None):
        """Create a FlowStats with the optional parameters below.

        Args:
            length (int): Length of this entry.
            table_id (int): ID of table flow came from.
            match (~pyof.v0x01.common.flow_match.Match): Description of fields.
            duration_sec (int): Time flow has been alive in seconds.
            duration_nsec (int): Time flow has been alive in nanoseconds in
                addition to duration_sec.
            priority (int): Priority of the entry. Only meaningful when this
                is not an exact-match entry.
            idle_timeout (int): Number of seconds idle before expiration.
            hard_timeout (int): Number of seconds before expiration.
            cookie (int): Opaque controller-issued identifier.
            packet_count (int): Number of packets in flow.
            byte_count (int): Number of bytes in flow.
            actions (:class:`~pyof.v0x01.common.actions.ListOfActions`):
                List of Actions.
        """
        super().__init__()
        self.length = length
        self.table_id = table_id
        self.match = match
        self.duration_sec = duration_sec
        self.duration_nsec = duration_nsec
        self.priority = priority
        self.idle_timeout = idle_timeout
        self.hard_timeout = hard_timeout
        self.cookie = cookie
        self.packet_count = packet_count
        self.byte_count = byte_count
        self.actions = [] if actions is None else actions

    def unpack(self, buff, offset=0):
        """Unpack *buff* into this object.

        Do nothing, since the _length is already defined and it is just a Pad.
        Keep buff and offset just for compability with other unpack methods.

        Args:
            buff (bytes): Buffer where data is located.
            offset (int): Where data stream begins.
        """
        self.length = UBInt16()
        self.length.unpack(buff, offset)
        max_length = offset + self.length.value
        super().unpack(buff[:max_length], offset)