Passed
Pull Request — master (#449)
by
unknown
01:55
created

ActionDecNWTTL.__init__()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.125

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
ccs 1
cts 2
cp 0.5
rs 10
cc 1
crap 1.125
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
10
# Third-party imports
11
12 1
__all__ = ('ActionExperimenterHeader', 'ActionGroup', 'ActionHeader',
13
           'ActionCopyTTLIn', 'ActionCopyTTLOut', 'ActionDecMPLSTTL',
14
           'ActionSetMPLSTTL', 'ActionDecNWTTL', 'ActionSetNWTTL',
15
           'ActionOutput', 'ActionPopMPLS', 'ActionPopPBB', 'ActionPopVLAN',
16
           'ActionPush', 'ActionSetField', 'ActionSetQueue', 'ActionType',
17
           'ControllerMaxLen', 'ListOfActions')
18
19
# Enums
20
21
22 1
class ActionType(IntEnum):
23
    """Actions associated with flows and packets."""
24
25
    #: Output to switch port.
26 1
    OFPAT_OUTPUT = 0
27
    #: Copy TTL "outwards" -- from next-to-outermost to outermost
28 1
    OFPAT_COPY_TTL_OUT = 11
29
    #: Copy TTL "inwards" -- from outermost to next-to-outermost
30 1
    OFPAT_COPY_TTL_IN = 12
31
    #: MPLS TTL
32 1
    OFPAT_SET_MPLS_TTL = 15
33
    #: Decrement MPLS TTL
34 1
    OFPAT_DEC_MPLS_TTL = 16
35
    #: Push a new VLAN tag
36 1
    OFPAT_PUSH_VLAN = 17
37
    #: Pop the outer VLAN tag
38 1
    OFPAT_POP_VLAN = 18
39
    #: Push a new MPLS tag
40 1
    OFPAT_PUSH_MPLS = 19
41
    #: Pop the outer MPLS tag
42 1
    OFPAT_POP_MPLS = 20
43
    #: Set queue id when outputting to a port
44 1
    OFPAT_SET_QUEUE = 21
45
    #: Apply group.
46 1
    OFPAT_GROUP = 22
47
    #: IP TTL.
48 1
    OFPAT_SET_NW_TTL = 23
49
    #: Decrement IP TTL.
50 1
    OFPAT_DEC_NW_TTL = 24
51
    #: Set a header field using OXM TLV format.
52 1
    OFPAT_SET_FIELD = 25
53
    #: Push a new PBB service tag (I-TAG)
54 1
    OFPAT_PUSH_PBB = 26
55
    #: Pop the outer PBB service tag (I-TAG)
56 1
    OFPAT_POP_PBB = 27
57
    #: Experimenter type
58 1
    OFPAT_EXPERIMENTER = 0xffff
59
60
61 1
class ControllerMaxLen(IntEnum):
62
    """A max_len of OFPCML_NO_BUFFER means not to buffer.
63
64
    The packet should be sent.
65
    """
66
67
    #: maximum max_len value which can be used to request a specific byte
68
    #:     length.
69 1
    OFPCML_MAX = 0xffe5
70
    #: indicates that no buffering should be applied and the whole packet is to
71
    #:     be sent to the controller.
72 1
    OFPCML_NO_BUFFER = 0xffff
73
74
75
# Classes
76
77
78 1
class ActionHeader(GenericStruct):
79
    """Action header that is common to all actions.
80
81
    The length includes the header and any padding used to make the action
82
    64-bit aligned.
83
    NB: The length of an action *must* always be a multiple of eight.
84
    """
85
86
    #: One of OFPAT_*.
87 1
    action_type = UBInt16(enum_ref=ActionType)
88
    #: Length of action, including this header. This is the length of actions,
89
    #:    including any padding to make it 64-bit aligned.
90 1
    length = UBInt16()
91
    # Pad for 64-bit alignment.
92
    # This should not be implemented, as each action type has its own padding.
93
    # pad = Pad(4)
94
95 1
    _allowed_types = ()
96
97 1
    def __init__(self, action_type=None, length=None):
98
        """Create an ActionHeader with the optional parameters below.
99
100
        Args:
101
            action_type (~pyof.v0x04.common.action.ActionType):
102
                The type of the action.
103
            length (int): Length of action, including this header.
104
        """
105
        super().__init__()
106
        self.action_type = action_type
107
        self.length = length
108
109 1
    def unpack(self, buff, offset=0):
110
        """Unpack a binary message into this object's attributes.
111
112
        Unpack the binary value *buff* and update this object attributes based
113
        on the results.
114
115
        Args:
116
            buff (bytes): Binary data package to be unpacked.
117
            offset (int): Where to begin unpacking.
118
119
        Raises:
120
            Exception: If there is a struct unpacking error.
121
122
        """
123
        self.action_type = UBInt16(enum_ref=ActionType)
124
        self.action_type.unpack(buff, offset)
125
126
        for cls in ActionHeader.__subclasses__():
127
            if self.action_type.value in cls.get_allowed_types():
128
                self.__class__ = cls
129
                break
130
131
        super().unpack(buff, offset)
132
133 1
    @classmethod
134
    def get_allowed_types(cls):
135
        """Return allowed types for the class."""
136
        return cls._allowed_types
137
138
139 1
class ActionExperimenterHeader(ActionHeader):
140
    """Action structure for OFPAT_EXPERIMENTER."""
141
142 1
    experimenter = UBInt32()
143
144 1
    _allowed_types = ActionType.OFPAT_EXPERIMENTER,
145
146 1
    def __init__(self, length=None, experimenter=None):
147
        """Create ActionExperimenterHeader with the optional parameters below.
148
149
        Args:
150
            experimenter (int): The experimenter field is the Experimenter ID,
151
                which takes the same form as in struct ofp_experimenter.
152
        """
153
        super().__init__(action_type=ActionType.OFPAT_EXPERIMENTER)
154
        self.length = length
155
        self.experimenter = experimenter
156
157
158 1
class ActionGroup(ActionHeader):
159
    """Action structure for OFPAT_GROUP."""
160
161 1
    group_id = UBInt32()
162
163 1
    _allowed_types = ActionType.OFPAT_GROUP,
164
165 1
    def __init__(self, group_id=None):
166
        """Create an ActionGroup with the optional parameters below.
167
168
        Args:
169
            group_id (int): The group_id indicates the group used to process
170
                this packet. The set of buckets to apply depends on the group
171
                type.
172
        """
173
        super().__init__(action_type=ActionType.OFPAT_GROUP, length=8)
174
        self.group_id = group_id
175
176
177 1
class ActionDecMPLSTTL(ActionHeader):
178
    """Action structure for OFPAT_DEC_MPLS_TTL."""
179
180 1
    pad = Pad(4)
181
182 1
    _allowed_types = ActionType.OFPAT_DEC_MPLS_TTL,
183
184 1
    def __init__(self):
185
        """Create an ActionDecMPLSTTL."""
186
        super().__init__(action_type=ActionType.OFPAT_DEC_MPLS_TTL, length=8)
187
188
189 1
class ActionSetMPLSTTL(ActionHeader):
190
    """Action structure for OFPAT_SET_MPLS_TTL."""
191
192 1
    mpls_ttl = UBInt8()
193 1
    pad = Pad(3)
194
195 1
    _allowed_types = ActionType.OFPAT_SET_MPLS_TTL,
196
197 1
    def __init__(self, mpls_ttl=None):
198
        """Create an ActionSetMPLSTTL with the optional parameters below.
199
200
        Args:
201
            mpls_ttl (int): The mpls_ttl field is the MPLS TTL to set.
202
        """
203
        super().__init__(action_type=ActionType.OFPAT_SET_MPLS_TTL, length=8)
204
        self.mpls_ttl = mpls_ttl
205
206
207 1
class ActionCopyTTLIn(ActionHeader):
208
    """Action structure for OFPAT_COPY_TTL_IN."""
209
210 1
    pad = Pad(4)
211
212 1
    _allowed_types = ActionType.OFPAT_COPY_TTL_IN,
213
214 1
    def __init__(self):
215
        """Create an ActionCopyTTLIn."""
216
        super().__init__(action_type=ActionType.OFPAT_COPY_TTL_IN, length=8)
217
218
219 1
class ActionCopyTTLOut(ActionHeader):
220
    """Action structure for OFPAT_COPY_TTL_OUT."""
221
222 1
    pad = Pad(4)
223
224 1
    _allowed_types = ActionType.OFPAT_COPY_TTL_OUT,
225
226 1
    def __init__(self):
227
        """Create an ActionCopyTTLOut."""
228
        super().__init__(action_type=ActionType.OFPAT_COPY_TTL_OUT, length=8)
229
230
231 1
class ActionPopVLAN(ActionHeader):
232
    """Action structure for OFPAT_POP_VLAN."""
233
234 1
    pad = Pad(4)
235
236 1
    _allowed_types = ActionType.OFPAT_POP_VLAN,
237
238 1
    def __init__(self):
239
        """Create an ActionPopVLAN."""
240
        super().__init__(action_type=ActionType.OFPAT_POP_VLAN, length=8)
241
242
243 1
class ActionPopPBB(ActionHeader):
244
    """Action structure for OFPAT_POP_PBB."""
245
246 1
    pad = Pad(4)
247
248 1
    _allowed_types = ActionType.OFPAT_POP_PBB,
249
250 1
    def __init__(self):
251
        """Create an ActionPopPBB."""
252
        super().__init__(action_type=ActionType.OFPAT_POP_PBB, length=8)
253
254
255 1
class ActionDecNWTTL(ActionHeader):
256
    """Action structure for OFPAT_DEC_NW_TTL."""
257
258 1
    pad = Pad(4)
259
260 1
    _allowed_types = ActionType.OFPAT_DEC_NW_TTL,
261
262 1
    def __init__(self):
263
        """Create a ActionDecNWTTL."""
264
        super().__init__(action_type=ActionType.OFPAT_DEC_NW_TTL, length=8)
265
266
267 1
class ActionSetNWTTL(ActionHeader):
268
    """Action structure for OFPAT_SET_NW_TTL."""
269
270 1
    nw_ttl = UBInt8()
271 1
    pad = Pad(3)
272
273 1
    _allowed_types = ActionType.OFPAT_SET_NW_TTL,
274
275 1
    def __init__(self, nw_ttl=None):
276
        """Create an ActionSetNWTTL with the optional parameters below.
277
278
        Args:
279
            nw_ttl (int): the TTL address to set in the IP header.
280
        """
281
        super().__init__(action_type=ActionType.OFPAT_SET_NW_TTL, length=8)
282
        self.nw_ttl = nw_ttl
283
284
285 1
class ActionOutput(ActionHeader):
286
    """Defines the actions output.
287
288
    Action structure for :attr:`ActionType.OFPAT_OUTPUT`, which sends packets
289
    out :attr:`port`. When the :attr:`port` is the
290
    :attr:`.Port.OFPP_CONTROLLER`, :attr:`max_length` indicates the max number
291
    of bytes to send. A :attr:`max_length` of zero means no bytes of the packet
292
    should be sent.
293
    """
294
295 1
    port = UBInt32()
296 1
    max_length = UBInt16()
297 1
    pad = Pad(6)
298
299 1
    _allowed_types = ActionType.OFPAT_OUTPUT,
300
301 1
    def __init__(self, port=None, max_length=None):
302
        """Create a ActionOutput with the optional parameters below.
303
304
        Args:
305
            port (:class:`Port` or :class:`int`): Output port.
306
            max_length (int): Max length to send to controller.
307
        """
308
        super().__init__(action_type=ActionType.OFPAT_OUTPUT, length=16)
309
        self.port = port
310
        self.max_length = max_length
311
312
313 1
class ActionPopMPLS(ActionHeader):
314
    """Action structure for OFPAT_POP_MPLS."""
315
316 1
    ethertype = UBInt16()
317 1
    pad = Pad(2)
318
319 1
    _allowed_types = ActionType.OFPAT_POP_MPLS,
320
321 1
    def __init__(self, ethertype=None):
322
        """Create an ActionPopMPLS with the optional parameters below.
323
324
        Args:
325
            ethertype (int): indicates the Ethertype of the payload.
326
        """
327
        super().__init__(action_type=ActionType.OFPAT_POP_MPLS)
328
        self.ethertype = ethertype
329
330
331 1
class ActionPush(ActionHeader):
332
    """Action structure for OFPAT_PUSH_[VLAN/MPLS/PBB]."""
333
334 1
    ethertype = UBInt16()
335 1
    pad = Pad(2)
336
337 1
    _allowed_types = (ActionType.OFPAT_PUSH_VLAN, ActionType.OFPAT_PUSH_MPLS,
338
                      ActionType.OFPAT_PUSH_PBB)
339
340 1
    def __init__(self, action_type=None, ethertype=None):
341
        """Create a ActionPush with the optional parameters below.
342
343
        Args:
344
            action_type (:class:`ActionType`): indicates which tag will be
345
            pushed (VLAN, MPLS, PBB).
346
            ethertype (int): indicates the Ethertype of the new tag.
347
        """
348
        super().__init__(action_type, length=8)
349
        self.ethertype = ethertype
350
351
352 1
class ActionSetField(GenericStruct):
353
    """Action structure for OFPAT_SET_FIELD."""
354
355
    #: OFPAT_SET_FIELD.
356 1
    action_type = UBInt16(ActionType.OFPAT_SET_FIELD, enum_ref=ActionType)
357
    #: Length is padded to 64 bits.
358 1
    length = UBInt16()
359
    #: OXM TLV - Make compiler happy
360 1
    field1 = UBInt8()
361 1
    field2 = UBInt8()
362 1
    field3 = UBInt8()
363 1
    field4 = UBInt8()
364
365 1
    def __init__(self, length=None, field1=None, field2=None, field3=None,
366
                 field4=None):
367
        """Create a ActionSetField with the optional parameters below.
368
369
        Args:
370
            length (int): length padded to 64 bits, followed by exactly
371
                          oxm_len bytes containing a single OXM TLV, then
372
                          exactly ((oxm_len + 4) + 7)/8*8 - (oxm_len + 4)
373
                          (between 0 and 7) bytes of all-zero bytes
374
            field1 (int): OXM field.
375
            field2 (int): OXM field.
376
            field3 (int): OXM field.
377
            field4 (int): OXM field.
378
        """
379
        super().__init__()
380
        self.length = length
381
        self.field1 = field1
382
        self.field2 = field2
383
        self.field3 = field3
384
        self.field4 = field4
385
386
387 1
class ActionSetQueue(ActionHeader):
388
    """Action structure for OFPAT_SET_QUEUE."""
389
390 1
    queue_id = UBInt32()
391
392 1
    _allowed_types = ActionType.OFPAT_SET_QUEUE,
393
394 1
    def __init__(self, queue_id=None):
395
        """Create an ActionSetQueue with the optional parameters below.
396
397
        Args:
398
            queue_id (int): The queue_id send packets to given queue on port.
399
        """
400
        super().__init__(action_type=ActionType.OFPAT_SET_QUEUE, length=8)
401
        self.queue_id = queue_id
402
403
404 1
class ListOfActions(FixedTypeList):
405
    """List of actions.
406
407
    Represented by instances of ActionHeader and used on ActionHeader objects.
408
    """
409
410 1
    def __init__(self, items=None):
411
        """Create a ListOfActions with the optional parameters below.
412
413
        Args:
414
            items (~pyof.v0x04.common.action.ActionHeader):
415
                Instance or a list of instances.
416
        """
417
        super().__init__(pyof_class=ActionHeader, items=items)
418