def header(self):
        """Header of the TLV Packet.

        The header is composed by the Type (7 bits) and Length (9 bits),
        summing up 16 bits. To achieve that, we need to do some bitshift
        operations.

        Returns:
            :class:`~pyof.foundation.basic_types.UBInt16`:
                Result after all operations.

        """
        return UBInt16(((self.tlv_type & 127) << 9) | (self.length & 511))
Esempio n. 2
0
    def unpack(self, buff=None, offset=0):
        """Unpack *buff* into this object.

        This method will convert a binary data into a readable value according
        to the attribute format.

        Args:
            buff (bytes): Binary buffer.
            offset (int): Where to begin unpacking.

        Raises:
            :exc:`~.exceptions.UnpackException`: If unpack fails.

        """
        band_type = UBInt16(enum_ref=MeterBandType)
        band_type.unpack(buff, offset)
        self.__class__ = MeterBandType(band_type.value).find_class()

        length = UBInt16()
        length.unpack(buff, offset=offset + 2)

        super().unpack(buff[:offset + length.value], offset)
Esempio n. 3
0
class PacketIn(GenericMessage):
    """Packet received on port (datapath -> controller)."""

    #: :class:`~.header.Header`: OpenFlow Header
    header = Header(message_type=Type.OFPT_PACKET_IN)
    #: ID assigned by datapath.
    buffer_id = UBInt32()
    #: Full length of frame.
    total_len = UBInt16()
    #: Reason packet is being sent (one of OFPR_*),
    reason = UBInt8(enum_ref=PacketInReason)
    #: ID of the table that was looked up.
    table_id = UBInt8()
    #: Cookie of the flow entry that was looked up.
    cookie = UBInt64()
    #: Packet metadata. Variable size.
    match = Match()
    #: Align to 64 bit + 16 bit
    pad = Pad(2)
    #: Ethernet frame whose length is inferred from header.length.
    #: The padding bytes preceding the Ethernet frame ensure that the IP
    #: header (if any) following the Ethernet header is 32-bit aligned.
    data = BinaryData()

    def __init__(self, xid=None, buffer_id=None, total_len=None, reason=None,
                 table_id=None, cookie=None, match=None, data=b''):
        """Assign parameters to object attributes.

        Args:
            xid (int): Header's xid.
            buffer_id (int): ID assigned by datapath.
            total_len (int): Full length of frame.
            reason (PacketInReason): The reason why the packet is being sent
            table_id (int): ID of the table that was looked up
            cookie (int): Cookie of the flow entry that was looked up
            match (:class:`~.common.flow_match.Match`): Packet metadata.
                Variable size.
            data (bytes): Ethernet frame, halfway through 32-bit word, so the
                IP header is 32-bit aligned. The amount of data is inferred
                from the length field in the header. Because of padding,
                offsetof(struct ofp_packet_in, data) ==
                sizeof(struct ofp_packet_in) - 2.
        """
        super().__init__(xid)
        self.buffer_id = buffer_id
        self.total_len = total_len
        self.reason = reason
        self.table_id = table_id
        self.cookie = cookie
        self.match = match
        self.data = data
Esempio n. 4
0
class ErrorMsg(GenericMessage):
    """OpenFlow Error Message.

    This message does not contain a body in addition to the OpenFlow Header.
    """

    #: :class:`~.header.Header`: OpenFlow Header
    header = Header(message_type=Type.OFPT_ERROR)
    #: ErrorType enum item
    error_type = UBInt16(enum_ref=ErrorType)
    #: Error code associated with ErrorType
    code = UBInt16()
    #: Variable-length data interpreted based on the type and code. No padding.
    data = BinaryData()

    def __init__(self, xid=None, error_type=None, code=None, data=b''):
        """Assign parameters to object attributes.

        Args:
            xid (int): To be included in the message header.
            error_type (ErrorType): Error type.
            code (Enum): Error code.
            data: Its content is specified in the error code documentation.
                Unless specified otherwise, the data field contains at least
                64 bytes of the failed request that caused the error message to
                be generated, if the failed request is shorter than 64 bytes it
                should be the full request without any padding.
        """
        super().__init__(xid)
        self.error_type = error_type
        self.code = code
        self.data = data

    def unpack(self, buff, offset=0):
        """Unpack binary data into python object."""
        super().unpack(buff, offset)
        code_class = ErrorType(self.error_type).get_class()
        self.code = code_class(self.code)
Esempio n. 5
0
    def __init__(self, type=InstructionType, length=None, exp_data=None):
        """The instruction_ids field is the list of instructions supported by this table.
        The elements of that list are variable in size to enable expressing experimenter
         instructions. Non-experimenter instructions are 4 bytes.

            Args:
                type(InstructionType): One of OFPIT_*.
                length(int): Length is 4 or experimenter defined.
                exp_data(int): Optional experimenter id + data.
        """
        super().__init__()
        self.type = type
        self.length = UBInt16(4) if length is None else length
        self.exp_data = exp_data
Esempio n. 6
0
    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)
Esempio n. 7
0
class SwitchConfig(GenericMessage):
    """Used as base class for SET_CONFIG and GET_CONFIG_REPLY messages."""

    #: OpenFlow :class:`~pyof.v0x04.common.header.Header`
    header = Header()
    flags = UBInt16(enum_ref=ConfigFlag)
    miss_send_len = UBInt16()

    def __init__(self,
                 xid=None,
                 flags=ConfigFlag.OFPC_FRAG_NORMAL,
                 miss_send_len=ControllerMaxLen.OFPCML_NO_BUFFER):
        """Create a SwitchConfig with the optional parameters below.

        Args:
            xid (int): xid to be used on the message header.
            flags (ConfigFlag): OFPC_* flags.
            miss_send_len (int): UBInt16 max bytes of new flow that the
                datapath should send to the controller.
        """
        super().__init__(xid)
        self.flags = flags
        self.miss_send_len = miss_send_len
class ActionDLAddr(ActionHeader):
    """Action structure for :attr:`ActionType.OFPAT_SET_DL_SRC` or _DST."""

    dl_addr_type = UBInt16(enum_ref=ActionType)
    length = UBInt16(16)
    dl_addr = HWAddress()
    #: Pad for bit alignment.
    pad = Pad(6)

    def __init__(self, dl_addr_type=None, dl_addr=None):
        """The following constructor parameters are optional.

        Args:
            dl_addr_type (ActionType): :attr:`~ActionType.OFPAT_SET_DL_SRC` or
                :attr:`~ActionType.OFPAT_SET_DL_DST`.
            dl_addr (:class:`~.HWAddress`): Ethernet address.
                Defaults to None.
        """
        super().__init__()
        self.dl_addr_type = dl_addr_type
        self.dl_addr = dl_addr
        self.allowed_types = (ActionType.OFPAT_SET_DL_SRC,
                              ActionType.OFPAT_SET_DL_DST)
class ActionVlanVid(ActionHeader):
    """Action structure for :attr:`ActionType.OFPAT_SET_VLAN_VID`.

    .. note:: The vlan_vid field is 16 bits long,
              when an actual VLAN id is only 12 bits.
              The value 0xffff is used to indicate that no VLAN id was set
    """

    action_type = UBInt16(ActionType.OFPAT_SET_VLAN_VID, enum_ref=ActionType)
    length = UBInt16(8)
    vlan_id = UBInt16()
    #: Pad for bit alignment.
    pad2 = Pad(2)

    def __init__(self, vlan_id=None):
        """The following constructor parameters are optional.

        Args:
            vlan_id (int): VLAN priority.
        """
        super().__init__()
        self.vlan_id = vlan_id
        self.allowed_types = ActionType.OFPAT_SET_VLAN_VID,
Esempio n. 10
0
    def unpack(self, buffer, offset=0):
        """Unpack a binary message into this object's attributes.

        Unpack the binary value *buff* and update this object attributes based
        on the results.

        Args:
            buffer (bytes): Binary data package to be unpacked.
            offset (int): Where to begin unpacking.

        Raises:
            Exception: If there is a struct unpacking error.
        """
        prio_cfi_id = UBInt16()
        prio_cfi_id.unpack(buffer[offset:2])

        self.pcp = prio_cfi_id.value >> 13
        self.cfi = (prio_cfi_id.value & 0x1000) >> 12
        self.vid = prio_cfi_id.value & 0xfff

        etype = UBInt16()
        etype.unpack(buffer[offset+2:4])
        self.ether_type = etype.value
Esempio n. 11
0
class InstructionGotoTable(GenericStruct):
    """Instruction structure for OFPIT_GOTO_TABLE."""

    #: OFPIT_GOTO_TABLE.
    instruction_type = UBInt16(InstructionType.OFPIT_GOTO_TABLE,
                               enum_ref=InstructionType)
    #: Length of this struct in bytes.
    length = UBInt16()
    #: Set next table in the lookup pipeline.
    table_id = UBInt8()
    #: Pad to 64 bits.
    pad = Pad(3)

    def __init__(self, length=None, table_id=None):
        """Instruction structure for OFPIT_GOTO_TABLE.

        Args:
            - length (int): Length of this struct in bytes.
            - table_id (int): set next table in the lookup pipeline.
        """
        super().__init__()
        self.length = length
        self.table_id = table_id
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
Esempio n. 13
0
class ActionOutput(GenericStruct):
    """Defines the actions output.

    Action structure for :attr:`ActionType.OFPAT_OUTPUT`, which sends packets
    out :attr:`port`. When the :attr:`port` is the
    :attr:`.Port.OFPP_CONTROLLER`, :attr:`max_length` indicates the max number
    of bytes to send. A :attr:`max_length` of zero means no bytes of the packet
    should be sent.
    """

    #: OFPAT_OUTPUT.
    action_type = UBInt16(ActionType.OFPAT_OUTPUT, enum_ref=ActionType)
    #: Length is 16.
    length = UBInt16(16)
    #: Output port.
    port = UBInt16()
    #: Max length to send to controller.
    max_length = UBInt16()
    #: Pad to 64 bits.
    pad = Pad(6)

    def __init__(self,
                 action_type=None,
                 length=None,
                 port=None,
                 max_length=None):
        """The following constructor parameters are optional.

        Args:
            port (:class:`Port` or :class:`int`): Output port.
            max_length (int): Max length to send to controller.
        """
        super().__init__()
        self.action_type = action_type
        self.length = length
        self.port = port
        self.max_length = max_length
Esempio n. 14
0
class Bucket(GenericStruct):
    """Bucket for use in groups."""

    length = UBInt16()
    weight = UBInt16()
    watch_port = UBInt32()
    watch_group = UBInt32()
    pad = Pad(4)
    actions = FixedTypeList(ActionHeader)

    def __init__(self,
                 length=None,
                 weight=None,
                 watch_port=None,
                 watch_group=None,
                 actions=None):
        """Initialize all instance variables.

        Args:
            length (int): Length the bucket in bytes, including this header and
                any padding to make it 64-bit aligned.
            weight (int): Relative weight of bucket. Only defined for select
                groups.
            watch_port (int): Port whose state affects whether this bucket is
                live. Only required for fast failover groups.
            watch_group (int): Group whose state affects whether this bucket is
                live. Only required for fast failover groups.
            actions (~pyof.v0x04.common.action.ListOfActions): The action
                length is inferred from the length field in the header.

        """
        super().__init__()
        self.length = length
        self.weight = weight
        self.watch_port = watch_port
        self.watch_group = watch_group
        self.actions = actions
Esempio n. 15
0
class Ethernet(GenericStruct):
    destination = HWAddress()
    source = HWAddress()
    type = UBInt16()
    data = BinaryData()

    def __init__(self, destination=None, source=None, type=None, data=b''):
        super().__init__()
        self.destination = destination
        self.source = source
        self.type = type
        self.data = data

    def get_hash(self):
        return hash(self.pack())
Esempio n. 16
0
class PacketIn(GenericMessage):
    """Packet received on port (datapath -> controller)."""

    #: :class:`~pyof.v0x01.common.header.Header`: OpenFlow Header
    header = Header(message_type=Type.OFPT_PACKET_IN)
    buffer_id = UBInt32()
    total_len = UBInt16()
    in_port = UBInt16()
    reason = UBInt8(enum_ref=PacketInReason)
    #: Align to 32-bits.
    pad = Pad(1)
    data = BinaryData()

    def __init__(self, xid=None, buffer_id=NO_BUFFER, total_len=None,
                 in_port=None, reason=None, data=b''):
        """Assign parameters to object attributes.

        Args:
            xid (int): Header's xid.
            buffer_id (int): ID assigned by datapath.
            total_len (int): Full length of frame.
            in_port (int): Port on which frame was received.
            reason (~pyof.v0x01.asynchronous.packet_in.PacketInReason):
                The reason why the packet is being sent
            data (bytes): Ethernet frame, halfway through 32-bit word, so the
                IP header is 32-bit aligned. The amount of data is inferred
                from the length field in the header. Because of padding,
                offsetof(struct ofp_packet_in, data) ==
                sizeof(struct ofp_packet_in) - 2.
        """
        super().__init__(xid)
        self.buffer_id = buffer_id
        self.total_len = total_len
        self.in_port = in_port
        self.reason = reason
        self.data = data
Esempio n. 17
0
class TableModPropVacancy(GenericStruct):
    """Vacancy table mod property"""

    #: OFPTMPT_VACANCY
    type = UBInt16()
    #: Length in bytes of this property
    length = UBInt16()
    #: Vacancy threshold when space decreases (%)
    vacancy_down = UBInt8()
    #: Vacancy threshold when space increases (%)
    vacancy_up = UBInt8()
    #: Current vacancy (%) - only in ofp_table_desc
    vacancy = UBInt8()
    #: Align to 64 bits
    pad = Pad(1)

    def __init__(self, type=TableModPropType.OFPTMPT_VACANCY, length=None, vacancy_down=None, vacancy_up=None,
                 vacancy=None):
        super().__init__()
        self.type = type
        self.length = length
        self.vacancy_down = vacancy_down
        self.vacancy_up = vacancy_up
        self.vacancy = vacancy
Esempio n. 18
0
class InstructionWriteMetadata(InstructionHeader):
    """Instruction structure for OFPIT_WRITE_METADATA."""

    #: OFPIT_WRITE_METADATA
    type = UBInt16()
    #: Length is 24.
    len = UBInt16()
    #: Align to 64-bits
    pad = Pad(4)
    #: Metadata value to write
    metadata = UBInt64()
    #: Metadata write bitmask
    metadata_mask = UBInt64()

    def __init__(self, metadata=0, metadata_mask=0):
        """Create InstructionWriteMetadata with the optional parameters below.

        Args:
            metadata (int): Metadata value to write.
            metadata_mask (int): Metadata write bitmask.
        """
        super().__init__(InstructionType.OFPIT_WRITE_METADATA)
        self.metadata = metadata
        self.metadata_mask = metadata_mask
Esempio n. 19
0
class ActionPopMPLS(ActionHeader):
    """Action structure for OFPAT_POP_MPLS."""

    ethertype = UBInt16()
    pad = Pad(2)

    _allowed_types = (ActionType.OFPAT_POP_MPLS, )

    def __init__(self, ethertype=None):
        """Create an ActionPopMPLS with the optional parameters below.

        Args:
            ethertype (int): indicates the Ethertype of the payload.
        """
        super().__init__(action_type=ActionType.OFPAT_POP_MPLS)
        self.ethertype = ethertype
Esempio n. 20
0
class GroupStats(GenericStruct):
    """Body of reply to OFPMP_GROUP request."""

    length = UBInt16()
    #: Align to 64 bits.
    pad = Pad(2)
    group_id = UBInt32()
    ref_count = UBInt32()
    #: Align to 64 bits.
    pad2 = Pad(4)
    packet_count = UBInt64()
    byte_count = UBInt64()
    duration_sec = UBInt32()
    duration_nsec = UBInt32()
    bucket_stats = FixedTypeList(BucketCounter)

    def __init__(self,
                 length=None,
                 group_id=None,
                 ref_count=None,
                 packet_count=None,
                 byte_count=None,
                 duration_sec=None,
                 duration_nsec=None,
                 bucket_stats=None):
        """Create a GroupStats with the optional parameters below.

        Args:
            length: Length of this entry
            group_id: Group identifier
            ref_count: Number of flows or groups that directly forward
                to this group.
            packet_count: Number of packets processed by group
            byte_count: Number of bytes processed by group
            duration_sec: Time group has been alive in seconds
            duration_nsec: Time group has been alive in nanoseconds
            bucket_stats: List of stats of group buckets
        """
        super().__init__()
        self.length = length
        self.group_id = group_id
        self.ref_count = ref_count
        self.packet_count = packet_count
        self.byte_count = byte_count
        self.duration_sec = duration_sec
        self.duration_nsec = duration_nsec
        self.bucket_stats = bucket_stats
Esempio n. 21
0
class QueueGetConfigRequest(GenericMessage):
    """Query structure for configured queues on a port."""

    header = Header(message_type=Type.OFPT_QUEUE_GET_CONFIG_REQUEST)
    port = UBInt16(enum_ref=Port)
    #: Pad to 64-bits
    pad = Pad(2)

    def __init__(self, xid=None, port=None):
        """Create a QueueGetConfigRequest with the optional parameters below.

        Args:
            xid (int): xid of OpenFlow header
            port (~pyof.v0x01.common.phy_port.Port): Target port for the query
        """
        super().__init__(xid)
        self.port = port
Esempio n. 22
0
    def unpack(self, buff=None, offset=0):
        """Unpack *buff* into this object.

        This method will convert a binary data into a readable value according
        to the attribute format.

        Args:
            buff (bytes): Binary buffer.
            offset (int): Where to begin unpacking.

        Raises:
            :exc:`~.exceptions.UnpackException`: If unpack fails.

        """
        length = UBInt16()
        length.unpack(buff, offset)
        super().unpack(buff[:offset+length.value], offset)
class QueueGetConfigRequest(GenericMessage):
    """Query structure for configured queues on a port."""

    header = Header(message_type=Type.OFPT_GET_CONFIG_REQUEST)
    port = UBInt16(enum_ref=Port)
    #: Pad to 64-bits
    pad = Pad(2)

    def __init__(self, xid=None, port=None):
        """The constructor just assings parameters to object attributes.

        Args:
            xid (int): xid of OpenFlow header
            port (Port): Target port for the query
        """
        super().__init__(xid)
        self.port = port
Esempio n. 24
0
class QueuePropMinRate(GenericStruct):
    """Define the minimum-rate type queue."""

    prop_header = QueuePropHeader(
        queue_property=QueueProperties.OFPQT_MIN_RATE, length=16)
    rate = UBInt16()
    #: 64-bit alignmet.
    pad = Pad(6)

    def __init__(self, rate=None):
        """Create a QueuePropMinRate with the optional parameters below.

        Args:
            rate (int): In 1/10 of a percent (1000 -> 100%); >1000 -> disabled.
        """
        super().__init__()
        self.rate = rate
Esempio n. 25
0
class QueuePropMinRate(GenericStruct):
    """Minimum-rate queue property uses the following structure and fields."""

    prop_header = QueuePropHeader(property=QueueProperties.OFPQT_MIN_RATE,
                                  length=16)
    #: In 1/10 of a percent; >1000 -> disabled.
    rate = UBInt16()
    #: 64-bit alignmet.
    pad = Pad(6)

    def __init__(self, rate=None):
        """The contructor takes the paremeters below.

        Args:
            rate (int): In 1/10 of a percent (1000 -> 100%); >1000 -> disabled.
        """
        super().__init__()
        self.rate = rate
Esempio n. 26
0
class QueuePropMaxRate(GenericStruct):
    """Maximum-rate queue property uses the following structure and fields."""

    prop_header = QueuePropHeader(
        queue_property=QueueProperties.OFPQT_MAX_RATE, length=16)
    #: In 1/10 of a percent; >1000 -> disabled.
    rate = UBInt16()
    #: 64-bit alignmet.
    pad = Pad(6)

    def __init__(self, rate=None):
        """Create a QueuePropMaxRate with the optional parameters below.

        Args:
            rate (int): In 1/10 of a percent (1000 -> 100%); >1000 -> disabled.
        """
        super().__init__()
        self.rate = rate
Esempio n. 27
0
class PortStatsRequest(GenericStruct):
    """Body for ofp_stats_request of type OFPST_PORT."""

    port_no = UBInt16()
    #: Align to 64-bits.
    pad = Pad(6)

    def __init__(self, port_no=None):
        """The constructor just assings parameters to object attributes.

        Args:
            port_no (:class:`int`, :class:`.Port`): OFPST_PORT message must
                request statistics either for a single port (specified in
                ``port_no``) or for all ports (if port_no ==
                :attr:`.Port.OFPP_NONE`).
        """
        super().__init__()
        self.port_no = port_no
Esempio n. 28
0
class PortStatsRequest(GenericStruct):
    """Body for ofp_stats_request of type OFPST_PORT."""

    port_no = UBInt16()
    #: Align to 64-bits.
    pad = Pad(6)

    def __init__(self, port_no=Port.OFPP_NONE):
        """Create a PortStatsRequest with the optional parameters below.

        Args:
            port_no (:class:`int`, :class:`~pyof.v0x01.common.phy_port.Port`):
                OFPST_PORT message must request statistics either for a single
                port (specified in ``port_no``) or for all ports
                (if ``port_no`` == :attr:`.Port.OFPP_NONE`).
        """
        super().__init__()
        self.port_no = port_no
Esempio n. 29
0
class BundleAddMsg(GenericMessage):
    """ Message structure for OFPT_BUNDLE_ADD_MESSAGE.
        Adding a message in a bundle is done with"""

    header = Header(message_type=Type.OFPT_BUNDLE_ADD_MESSAGE)
    #: Identify the bundle
    bundle_id = UBInt32()
    #: Align to 64 bits
    pad = Pad()
    #: Bitmap of OFPBF_* flags.
    flags = UBInt16(enum_ref=BundleFlags)
    #: Message added to the bundle
    message = Header()
    """ If there is one property or more, ’message’ is followed by:
       Exactly (message.length + 7)/8*8 - (message.length) (between 0 and 7)
       bytes of all-zero bytes"""

    #: Bundle Property list
    property = ListOfBundleProperties()

    def __init__(self,
                 xid=None,
                 bundle_id=None,
                 flags=BundleFlags,
                 message=None,
                 properties=None):
        """Assign parameters to object attributes.

        Args:
            xid (int): :class:`~pyof.v0x05.common.header.Header`'s xid.
                Defaults to random.
            bundle_id (int): ID of the bundle. A 32 bit number chosen by the controller. The bundle
            identifier should be a bundle that has been previously opened and not yet closed
            flags (int): Bitmap of OFPBF_* flags
            message :a OpenFlow message to be added to the bundle, it can be any OpenFlow message that
            the switch can support in a bundle. The field xid in the message must be identical to the field xid of
            the OFPT_BUNDLE_ADD_MESSAGE message.

        """
        super().__init__(xid)
        self.bundle_id = bundle_id
        self.flags = flags
        self.message = message
        self.properties = properties
Esempio n. 30
0
    def test_hello_elem_version_bitmap(self):
        """
        Testing the class HelloElemVersionBitmap.
        Test support 2 versions (ver 1 = 0x01 and ver 1.3 = 0x04)
        Testing 2 version support ver 1 and ver 1.3 based on the specification's example.

        :return: None
        """

        ver1 = 0x01
        ver3 = 0x04
        ver = ver1 << ver3
        ver = ver | 2

        test_val = b'\x00\x01\x00\x08\x00\x00\x00\x12'
        self.test_object_hello_elem_version = Hello.HelloElemVersionBitmap(UBInt16(8), UBInt32(ver).pack())
        val = self.test_object_hello_elem_version.pack()

        self.assertEqual(test_val,val)