Passed
Pull Request — master (#425)
by Carlos Eduardo
02:30
created

InstructionClearAction.__init__()   A

Complexity

Conditions 2

Size

Total Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 3.6875

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 10
ccs 1
cts 4
cp 0.25
c 1
b 0
f 0
rs 9.4285
cc 2
crap 3.6875
1
"""Flow instructions to be executed.
2
3
The flow instructions associated with a flow table entry are executed when a
4
flow matches the entry.
5
"""
6
# System imports
7 1
from enum import IntEnum
8
9
# Local source tree imports
10 1
from pyof.foundation.base import GenericStruct
11 1
from pyof.foundation.basic_types import (
12
    FixedTypeList, Pad, UBInt8, UBInt16, UBInt32, UBInt64)
13 1
from pyof.v0x04.common.action import ListOfActions
14 1
from pyof.v0x04.controller2switch.meter_mod import Meter
15
16
# Third-party imports
17
18
19 1
__all__ = ('InstructionApplyAction', 'InstructionClearAction',
20
           'InstructionGotoTable', 'InstructionMeter', 'InstructionType',
21
           'InstructionWriteAction', 'InstructionWriteMetadata',
22
           'ListOfInstruction')
23
24
# Enums
25
26
27 1
class InstructionType(IntEnum):
28
    """List of instructions that are currently defined."""
29
30
    #: Setup the next table in the lookup pipeline
31 1
    OFPIT_GOTO_TABLE = 1
32
    #: Setup the metadata field for use later in pipeline
33 1
    OFPIT_WRITE_METADATA = 2
34
    #: Write the action(s) onto the datapath action set
35 1
    OFPIT_WRITE_ACTIONS = 3
36
    #: Applies the action(s) immediately
37 1
    OFPIT_APPLY_ACTIONS = 4
38
    #: Clears all actions from the datapath action set
39 1
    OFPIT_CLEAR_ACTIONS = 5
40
    #: Apply meter (rate limiter)
41 1
    OFPIT_METER = 6
42
    #: Experimenter instruction
43 1
    OFPIT_EXPERIMENTER = 0xFFFF
44
45 1
    def find_class(self):
46
        """Method used to return a class related with this type."""
47
        classes = {1: InstructionGotoTable, 2: InstructionWriteMetadata,
48
                   3: InstructionWriteAction, 4: InstructionApplyAction,
49
                   5: InstructionClearAction, 6: InstructionMeter}
50
        return classes.get(self.value, None)
51
52
53
# Classes
54
55 1
class Instruction(GenericStruct):
56
    """Generic Instruction class.
57
58
    This class represents a Generic Instruction that can be instanciated as
59
    'InstructionApplyAction', 'InstructionClearAction', 'InstructionGotoTable',
60
    'InstructionMeter', 'InstructionWriteAction', 'InstructionWriteMetadata'.
61
    """
62
63 1
    instruction_type = UBInt16(enum_ref=InstructionType)
64 1
    length = UBInt16()
65
66 1
    def __init__(self, instruction_type=None):
67
        """Constructor of Generic Instruction receives the parameters bellow.
68
69
        Args:
70
            instruction_type(InstructionType): Type of instruction.
71
        """
72
        super().__init__()
73
        self.instruction_type = instruction_type
74
75 1
    def update_length(self):
76
        """Method used to update length attribute."""
77
        self.length = self.get_size()
78
79 1
    def unpack(self, buff=None, offset=0):
80
        """Unpack *buff* into this object.
81
82
        This method will convert a binary data into a readable value according
83
        to the attribute format.
84
85
        Args:
86
            buff (bytes): Binary buffer.
87
            offset (int): Where to begin unpacking.
88
89
        Raises:
90
            :exc:`~.exceptions.UnpackException`: If unpack fails.
91
        """
92
        instruction_type = UBInt16(enum_ref=InstructionType)
93
        instruction_type.unpack(buff, offset)
94
        self.__class__ = InstructionType(instruction_type.value).find_class()
95
96
        length = UBInt16()
97
        length.unpack(buff, offset=offset+2)
98
99
        super().unpack(buff[:offset+length.value], offset)
100
101
102 1
class InstructionApplyAction(Instruction):
103
    """Instruction structure for OFPIT_APPLY_ACTIONS.
104
105
    The :attr:`~actions` field is treated as a list, and the actions are
106
    applied to the packet in-order.
107
    """
108
109
    #: Align to 64-bits
110 1
    pad = Pad(4)
111
    #: Actions associated with OFPIT_APPLY_ACTIONS
112 1
    actions = ListOfActions()
113
114 1
    def __init__(self, actions=None):
115
        """The constructor just assigns parameters to object attributes.
116
117
        Args:
118
            actions (:class:`~.actions.ListOfActions`):
119
                Actions associated with OFPIT_APPLY_ACTIONS.
120
        """
121
        super().__init__(InstructionType.OFPIT_APPLY_ACTIONS)
122
        self.actions = actions if actions else []
123
        self.update_length()
124
125
126 1
class InstructionClearAction(Instruction):
127
    """Instruction structure for OFPIT_CLEAR_ACTIONS.
128
129
    This structure does not contain any actions.
130
    """
131
132
    #: Align to 64-bits
133 1
    pad = Pad(4)
134
    #: OFPIT_CLEAR_ACTIONS does not have any action on the list of actions.
135 1
    actions = ListOfActions()
136
137 1
    def __init__(self, actions=None):
138
        """The constructor just assigns parameters to object attributes.
139
140
        Args:
141
            actions (:class:`~.actions.ListOfActions`):
142
                Actions associated with OFPIT_CLEAR_ACTIONS.
143
        """
144
        super().__init__(InstructionType.OFPIT_CLEAR_ACTIONS)
145
        self.actions = actions if actions else []
146
        self.update_length()
147
148
149 1
class InstructionGotoTable(Instruction):
150
    """Instruction structure for OFPIT_GOTO_TABLE."""
151
152
    #: Set next table in the lookup pipeline.
153 1
    table_id = UBInt8()
154
    #: Pad to 64 bits.
155 1
    pad = Pad(3)
156
157 1
    def __init__(self, table_id=Meter.OFPM_ALL):
158
        """The constructor just assigns parameters to object attributes.
159
160
        Args:
161
            length (int): Length of this struct in bytes.
162
            table_id (int): set next table in the lookup pipeline.
163
        """
164
        super().__init__(InstructionType.OFPIT_GOTO_TABLE)
165
        self.table_id = table_id
166
        self.update_length()
167
168
169 1
class InstructionMeter(Instruction):
170
    """Instruction structure for OFPIT_METER.
171
172
    meter_id indicates which meter to apply on the packet.
173
    """
174
175
    #: Meter instance.
176 1
    meter_id = UBInt32()
177
178 1
    def __init__(self, meter_id=Meter.OFPM_ALL):
179
        """The constructor just assigns parameters to object attributes.
180
181
        Args:
182
            meter_id (int): Meter instance.
183
        """
184
        super().__init__(InstructionType.OFPIT_METER)
185
        self.meter_id = meter_id
186
187
188 1
class InstructionWriteAction(Instruction):
189
    """Instruction structure for OFPIT_WRITE_ACTIONS.
190
191
    The actions field must be treated as a SET, so the actions are not
192
    repeated.
193
    """
194
195
    #: Align to 64-bits
196 1
    pad = Pad(4)
197
    #: Actions associated with OFPIT_WRITE_ACTIONS
198 1
    actions = ListOfActions()
199
200 1
    def __init__(self, actions=None):
201
        """The constructor just assigns parameters to object attributes.
202
203
        Args:
204
            actions (:class:`~.actions.ListOfActions`):
205
                Actions associated with OFPIT_WRITE_ACTIONS.
206
        """
207
        super().__init__(InstructionType.OFPIT_WRITE_ACTIONS)
208
        self.actions = actions if actions else []
209
        self.update_length()
210
211
212 1
class InstructionWriteMetadata(Instruction):
213
    """Instruction structure for OFPIT_WRITE_METADATA."""
214
215
    #: Align to 64-bits
216 1
    pad = Pad(4)
217
    #: Metadata value to write
218 1
    metadata = UBInt64()
219
    #: Metadata write bitmask
220 1
    metadata_mask = UBInt64()
221
222 1
    def __init__(self, metadata=0, metadata_mask=0):
223
        """The constructor just assigns parameters to object attributes.
224
225
        Args:
226
            metadata (int): Metadata value to write.
227
            metadata_mask (int): Metadata write bitmask.
228
        """
229
        super().__init__(InstructionType.OFPIT_WRITE_METADATA)
230
        self.metadata = metadata
231
        self.metadata_mask = metadata_mask
232
        self.update_length()
233
234
235 1
class ListOfInstruction(FixedTypeList):
236
    """List of Instructions.
237
238
    Represented by instances of Instruction.
239
    """
240
241 1
    def __init__(self, items=None):
242
        """The constructor just assigns parameters to object attributes.
243
244
        Args:
245
            items (:class:`~pyof.v0x04.common.flow_instructions.Instruction`):
246
                Instance or a list of instances.
247
        """
248
        super().__init__(pyof_class=Instruction, items=items)
249