Test Failed
Pull Request — master (#392)
by
unknown
02:09
created

ActionSetField._pack()   A

Complexity

Conditions 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2.1481

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 8
ccs 2
cts 3
cp 0.6667
rs 9.4285
cc 2
crap 2.1481
1
"""Defines actions that may be associated with flows packets."""
2
# System imports
3 1
from enum import IntEnum
4
5
# Local source tree imports
6 1
from pyof.foundation.base import GenericStruct
7 1
from pyof.foundation.basic_types import (
8
    FixedTypeList, Pad, UBInt8, UBInt16, UBInt32)
9
from pyof.v0x01.common.flow_match import OxmTLV
10
11
# Third-party imports
12 1
13
__all__ = ('ActionExperimenterHeader', 'ActionGroup', 'ActionHeader',
14
           'ActionMPLSTTL', 'ActionNWTTL', 'ActionOutput', 'ActionPopMPLS',
15
           'ActionPush', 'ActionSetField', 'ActionSetQueue', 'ActionType',
16
           'ControllerMaxLen', 'ListOfActions')
17
18
# Enums
19
20 1
21
class ActionType(IntEnum):
22
    """Actions associated with flows and packets."""
23
24 1
    #: Output to switch port.
25
    OFPAT_OUTPUT = 0
26 1
    #: Copy TTL "outwards" -- from next-to-outermost to outermost
27
    OFPAT_COPY_TTL_OUT = 11
28 1
    #: Copy TTL "inwards" -- from outermost to next-to-outermost
29
    OFPAT_COPY_TTL_IN = 12
30 1
    #: MPLS TTL
31
    OFPAT_SET_MPLS_TTL = 15
32 1
    #: Decrement MPLS TTL
33
    OFPAT_DEC_MPLS_TTL = 16
34 1
    #: Push a new VLAN tag
35
    OFPAT_PUSH_VLAN = 17
36 1
    #: Pop the outer VLAN tag
37
    OFPAT_POP_VLAN = 18
38 1
    #: Push a new MPLS tag
39
    OFPAT_PUSH_MPLS = 19
40 1
    #: Pop the outer MPLS tag
41
    OFPAT_POP_MPLS = 20
42 1
    #: Set queue id when outputting to a port
43
    OFPAT_SET_QUEUE = 21
44 1
    #: Apply group.
45
    OFPAT_GROUP = 22
46 1
    #: IP TTL.
47
    OFPAT_SET_NW_TTL = 23
48 1
    #: Decrement IP TTL.
49
    OFPAT_DEC_NW_TTL = 24
50 1
    #: Set a header field using OXM TLV format.
51
    OFPAT_SET_FIELD = 25
52 1
    #: Push a new PBB service tag (I-TAG)
53
    OFPAT_PUSH_PBB = 26
54 1
    #: Pop the outer PBB service tag (I-TAG)
55
    OFPAT_POP_PBB = 27
56 1
    #: Experimenter type
57
    OFPAT_EXPERIMENTER = 0xffff
58
59 1
60
class ControllerMaxLen(IntEnum):
61
    """A max_len of OFPCML_NO_BUFFER means not to buffer.
62
63
    The packet should be sent.
64
    """
65
66
    #: maximum max_len value which can be used to request a specific byte
67 1
    #:     length.
68
    OFPCML_MAX = 0xffe5
69
    #: indicates that no buffering should be applied and the whole packet is to
70 1
    #:     be sent to the controller.
71
    OFPCML_NO_BUFFER = 0xffff
72
73
74
# Classes
75
76 1
77
class ActionExperimenterHeader(GenericStruct):
78
    """Action structure for OFPAT_EXPERIMENTER."""
79
80 1
    #: OFPAT_EXPERIMENTER.
81
    action_type = UBInt16(ActionType.OFPAT_EXPERIMENTER, enum_ref=ActionType)
82 1
    #: Length is multiple of 8.
83
    length = UBInt16()
84
    #: Experimenter ID which takes the same form as in struct
85 1
    #:     ofp_experimenter_header
86
    experimenter = UBInt32()
87 1
88
    def __init__(self, length=None, experimenter=None):
89
        """The constructor just assigns parameters to object attributes.
90
91
        Args:
92
            experimenter (int): The experimenter field is the Experimenter ID,
93
                which takes the same form as in struct ofp_experimenter.
94
        """
95
        super().__init__()
96
        self.length = length
97
        self.experimenter = experimenter
98
99 1
100
class ActionGroup(GenericStruct):
101
    """Action structure for OFPAT_GROUP."""
102
103 1
    #: OFPAT_GROUP.
104
    action_type = UBInt16(ActionType.OFPAT_GROUP, enum_ref=ActionType)
105 1
    #: Length is 8.
106
    length = UBInt16(8)
107 1
    #: Group identifier.
108
    group_id = UBInt32()
109 1
110
    def __init__(self, group_id=None):
111
        """The constructor just assigns parameters to object attributes.
112
113
        Args:
114
            group_id (int): The group_id indicates the group used to process
115
                this packet. The set of buckets to apply depends on the group
116
                type.
117
        """
118
        super().__init__()
119
        self.group_id = group_id
120
121 1
122
class ActionHeader(GenericStruct):
123
    """Action header that is common to all actions.
124
125
    The length includes the header and any padding used to make the action
126
    64-bit aligned.
127
    NB: The length of an action *must* always be a multiple of eight.
128
    """
129
130 1
    #: One of OFPAT_*.
131
    action_type = UBInt16(enum_ref=ActionType)
132
    #: Length of action, including this header. This is the length of actions,
133 1
    #:    including any padding to make it 64-bit aligned.
134
    length = UBInt16()
135 1
    #: Pad for 64-bit alignment.
136
    pad = Pad(4)
137 1
138
    def __init__(self, action_type=None, length=None):
139
        """The constructor just assigns parameters to object attributes.
140
141
        Args:
142
            action_type (~pyof.v0x04.common.action.ActionType):
143
                The type of the action.
144
            length (int): Length of action, including this header.
145
        """
146
        super().__init__()
147
        self.action_type = action_type
148
        self.length = length
149 1
150
151
class ActionMPLSTTL(GenericStruct):
152
    """Action structure for OFPAT_SET_MPLS_TTL."""
153 1
154
    #: OFPAT_SET_MPLS_TTL.
155 1
    action_type = UBInt16(ActionType.OFPAT_SET_MPLS_TTL, enum_ref=ActionType)
156
    #: Length is 8.
157 1
    length = UBInt16(8)
158
    #: MPLS TTL
159 1
    mpls_ttl = UBInt8()
160
    #: Padding
161 1
    pad = Pad(3)
162
163
    def __init__(self, mpls_ttl=None):
164
        """The constructor just assigns parameters to object attributes.
165
166
        Args:
167
            mpls_ttl (int): The mpls_ttl field is the MPLS TTL to set.
168
        """
169
        super().__init__()
170
        self.mpls_ttl = mpls_ttl
171 1
172
173
class ActionNWTTL(GenericStruct):
174
    """Action structure for OFPAT_SET_NW_TTL."""
175 1
176
    #: OFPAT_SET_NW_TTL.
177 1
    action_type = UBInt16(ActionType.OFPAT_SET_NW_TTL, enum_ref=ActionType)
178
    #: Length is 8.
179 1
    length = UBInt16(8)
180
    #: IP TTL
181 1
    nw_ttl = UBInt8()
182
    #: Padding
183 1
    pad = Pad(3)
184
185
    def __init__(self, nw_ttl=None):
186
        """The constructor just assigns parameters to object attributes.
187
188
        Args:
189
            nw_ttl (int): the TTL address to set in the IP header.
190
        """
191
        super().__init__()
192
        self.nw_ttl = nw_ttl
193 1
194
195
class ActionOutput(GenericStruct):
196
    """Defines the actions output.
197
198
    Action structure for :attr:`ActionType.OFPAT_OUTPUT`, which sends packets
199
    out :attr:`port`. When the :attr:`port` is the
200
    :attr:`.Port.OFPP_CONTROLLER`, :attr:`max_length` indicates the max number
201
    of bytes to send. A :attr:`max_length` of zero means no bytes of the packet
202
    should be sent.
203
    """
204 1
205
    #: OFPAT_OUTPUT.
206 1
    action_type = UBInt16(ActionType.OFPAT_OUTPUT, enum_ref=ActionType)
207
    #: Length is 16.
208 1
    length = UBInt16(16)
209
    #: Output port.
210 1
    port = UBInt16()
211
    #: Max length to send to controller.
212 1
    max_length = UBInt16()
213
    #: Pad to 64 bits.
214 1
    pad = Pad(6)
215
216
    def __init__(self, action_type=None, length=None, port=None,
217
                 max_length=None):
218
        """The constructor just assigns parameters to object attributes.
219
220
        Args:
221
            port (:class:`Port` or :class:`int`): Output port.
222
            max_length (int): Max length to send to controller.
223
        """
224
        super().__init__()
225
        self.action_type = action_type
226
        self.length = length
227
        self.port = port
228
        self.max_length = max_length
229 1
230
231
class ActionPopMPLS(GenericStruct):
232
    """Action structure for OFPAT_POP_MPLS."""
233 1
234
    #: OFPAT_POP_MPLS.
235 1
    action_type = UBInt16(ActionType.OFPAT_POP_MPLS, enum_ref=ActionType)
236
    #: Length is 8.
237 1
    length = UBInt16(8)
238
    #: Ethertype
239 1
    ethertype = UBInt16()
240
    #: Padding
241 1
    pad = Pad(2)
242
243
    def __init__(self, ethertype=None):
244
        """The constructor just assigns parameters to object attributes.
245
246
        Args:
247
            ethertype (int): indicates the Ethertype of the payload.
248
        """
249
        super().__init__()
250
        self.ethertype = ethertype
251 1
252
253
class ActionPush(GenericStruct):
254
    """Action structure for OFPAT_PUSH_VLAN/MPLS/PBB."""
255 1
256
    #: OFPAT_PUSH_VLAN/MPLS/PBB.
257 1
    action_type = UBInt16(enum_ref=ActionType)
258
    #: Length is 8.
259 1
    length = UBInt16(8)
260
    #: Ethertype
261 1
    ethertype = UBInt16()
262
    #: Padding
263 1
    pad = Pad(2)
264
265
    def __init__(self, ethertype=None):
266
        """The constructor just assigns parameters to object attributes.
267
268
        Args:
269
            ethertype (int): indicates the Ethertype of the new tag.
270
        """
271
        super().__init__()
272
        self.ethertype = ethertype
273 1
274
275
class ActionSetField(GenericStruct):
276
    """Action structure for OFPAT_SET_FIELD."""
277 1
278
    #: OFPAT_SET_FIELD.
279 1
    action_type = UBInt16(ActionType.OFPAT_SET_FIELD, enum_ref=ActionType)
280
    #: Length is padded to 64 bits.
281
    length = UBInt16()
282
    pad = Pad(length=4)
283
    #: OXM TLV - Make compiler happy
284
    field = OxmTLV()
285
286 1
    def __init__(self, length=None, field=None):
287 1
        """The constructor just assigns parameters to object attributes.
288 1
289 1
        Args:
290
            length (int): length padded to 64 bits, followed by exactly
291 1
                          oxm_len bytes containing a single OXM TLV, then
292
                          exactly ((oxm_len + 4) + 7)/8*8 - (oxm_len + 4)
293
                          (between 0 and 7) bytes of all-zero bytes
294
            field  (OcmTLV): OXM field.
295
        """
296
        super().__init__()
297
        self.length = length
298
        self.field = field
299
300
    def _get_size(self):
301
        super_size = super()._get_size()
302
        return super_size + (8 - (super_size % 8)) % 8
303
304
    def _update_length(self):
305
        self.length = self._get_size()
306
307
    def _pack(self):
308
        self._update_length()
309
        packet = super()._pack()
310 1
        super_size = len(packet)
311
        lacking_bytes = self._get_size() - super_size
312
        if lacking_bytes != 0:
313
            packet += Pad(lacking_bytes).pack()
314 1
        return packet
315
316 1
317
class ActionSetQueue(GenericStruct):
318 1
    """Action structure for OFPAT_SET_QUEUE."""
319
320 1
    #: OFPAT_SET_QUEUE.
321
    action_type = UBInt16(ActionType.OFPAT_SET_QUEUE, enum_ref=ActionType)
322
    #: Length is 8.
323
    length = UBInt16(8)
324
    #: Queue id for the packets.
325
    queue_id = UBInt32()
326
327
    def __init__(self, queue_id=None):
328
        """The constructor just assigns parameters to object attributes.
329
330 1
        Args:
331
            queue_id (int): The queue_id send packets to given queue on port.
332
        """
333
        super().__init__()
334
        self.queue_id = queue_id
335
336 1
337
class ListOfActions(FixedTypeList):
338
    """List of actions.
339
340
    Represented by instances of ActionHeader and used on ActionHeader objects.
341
    """
342 1
343
    def __init__(self, items=None):
344
        """The constructor just assigns parameters to object attributes.
345
346
        Args:
347
            items (~pyof.v0x04.common.action.ActionHeader):
348
                Instance or a list of instances.
349
        """
350
        super().__init__(pyof_class=ActionHeader, items=items)
351