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

ActionStripVlan.__init__()   A

Complexity

Conditions 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1.125

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 6
ccs 1
cts 2
cp 0.5
rs 9.4285
cc 1
crap 1.125
1
"""Defines actions that may be associated with flows packets."""
2
3
# System imports
4
5
# Local source tree imports
6 1
from pyof.foundation.base import GenericBitMask, GenericStruct
7 1
from pyof.foundation.basic_types import (
8
    FixedTypeList, HWAddress, Pad, UBInt8, UBInt16, UBInt32)
9 1
from pyof.foundation.constants import UBINT16_MAX_VALUE
10
11
# Third-party imports
12
13 1
__all__ = ('ActionType', 'ActionHeader', 'ActionOutput', 'ActionEnqueue',
14
           'ActionVlanVid', 'ActionVlanPCP', 'ActionDLAddr', 'ActionNWAddr',
15
           'ActionNWTos', 'ActionTPPort', 'ActionVendorHeader',
16
           'ListOfActions')
17
18
# Enums
19
20
21 1
class ActionType(GenericBitMask):
22
    """Actions associated with flows and packets."""
23
24
    #: Output to switch port.
25 1
    OFPAT_OUTPUT = 0
26
    #: Set the 802.1q VLAN id.
27 1
    OFPAT_SET_VLAN_VID = 1
28
    #: Set the 802.1q priority.
29 1
    OFPAT_SET_VLAN_PCP = 2
30
    #: Strip the 802.1q header.
31 1
    OFPAT_STRIP_VLAN = 3
32
    #: Ethernet source address.
33 1
    OFPAT_SET_DL_SRC = 4
34
    #: Ethernet destination address.
35 1
    OFPAT_SET_DL_DST = 5
36
    #: IP source address.
37 1
    OFPAT_SET_NW_SRC = 6
38
    #: IP destination address.
39 1
    OFPAT_SET_NW_DST = 7
40
    #: IP ToS (DSCP field, 6 bits).
41 1
    OFPAT_SET_NW_TOS = 8
42
    #: TCP/UDP source port.
43 1
    OFPAT_SET_TP_SRC = 9
44
    #: TCP/UDP destination port.
45 1
    OFPAT_SET_TP_DST = 10
46
    #: Output to queue.
47 1
    OFPAT_ENQUEUE = 11
48
    #: Vendor specific.
49 1
    OFPAT_VENDOR = 0xffff
50
51
52
# Classes
53
54
55 1
class ActionHeader(GenericStruct):
56
    """Defines the Header that is common to all actions."""
57
58 1
    action_type = UBInt16(enum_ref=ActionType)
59 1
    length = UBInt16()
60
    # Pad for 64-bit alignment.
61
    # This attribute will not be implemented since not all subclasses from
62
    # this class will hold it on the same place and with the same size.
63
    # pad = Pad(4)
64
65 1
    _allowed_types = ()
66
67 1
    def __init__(self, action_type=None, length=None):
68
        """The following constructor parameters are optional.
69
70
        Args:
71
            action_type (~pyof.v0x01.common.action.ActionType):
72
                The type of the action.
73
            length (int): Length of action, including this header.
74
        """
75 1
        super().__init__()
76 1
        self.action_type = action_type
77 1
        self.length = length
78
79 1
    def unpack(self, buff, offset=0):
80
        """Unpack a binary message into this object's attributes.
81
82
        Unpack the binary value *buff* and update this object attributes based
83
        on the results.
84
85
        Args:
86
            buff (bytes): Binary data package to be unpacked.
87
            offset (int): Where to begin unpacking.
88
89
        Raises:
90
            Exception: If there is a struct unpacking error.
91
        """
92 1
        self.action_type = UBInt16(enum_ref=ActionType)
93 1
        self.action_type.unpack(buff, offset)
94
95 1
        for cls in ActionHeader.__subclasses__():
96 1
            if self.action_type.value in cls.get_allowed_types():
97 1
                self.__class__ = cls
98 1
                break
99
100 1
        super().unpack(buff, offset)
101
102 1
    @classmethod
103
    def get_allowed_types(cls):
104
        """Return allowed types for the class."""
105 1
        return cls._allowed_types
106
107
108 1
class ActionOutput(ActionHeader):
109
    """Defines the actions output.
110
111
    Action structure for :attr:`ActionType.OFPAT_OUTPUT`, which sends packets
112
    out :attr:`port`. When the :attr:`port` is the
113
    :attr:`.Port.OFPP_CONTROLLER`, :attr:`max_length` indicates the max number
114
    of bytes to send. A :attr:`max_length` of zero means no bytes of the packet
115
    should be sent.
116
    """
117
118 1
    port = UBInt16()
119 1
    max_length = UBInt16()
120
121 1
    _allowed_types = ActionType.OFPAT_OUTPUT,
122
123 1
    def __init__(self, port=None, max_length=UBINT16_MAX_VALUE):
124
        """The following constructor parameters are optional.
125
126
        Args:
127
            port (:class:`~pyof.v0x01.common.phy_port.Port` or :class:`int`):
128
                Output port.
129
            max_length (int): Max length to send to controller.
130
        """
131 1
        super().__init__(action_type=ActionType.OFPAT_OUTPUT, length=8)
132 1
        self.port = port
133 1
        self.max_length = max_length
134
135
136 1
class ActionStripVlan(ActionHeader):
137
    """Strips VLAN information from packets.
138
139
    Action defined for switches to remove the 802.1q VLAN information from
140
    packets.
141
    """
142
143 1
    pad = Pad(4)
144
145 1
    _allowed_types = ActionType.OFPAT_STRIP_VLAN,
146
147 1
    def __init__(self):
148
        """Construct the ActionHeader with the appropriate ActionType.
149
150
        No parameters need to be specified.
151
        """
152
        super().__init__(action_type=ActionType.OFPAT_STRIP_VLAN, length=8)
153
154
155 1
class ActionEnqueue(ActionHeader):
156
    """Send packets to a queue's port.
157
158
    A switch may support only queues that are tied to specific PCP/TOS bits.
159
    In that case, we cannot map an arbitrary flow to a specific queue,
160
    therefore the action ENQUEUE is not supported. The user can still use
161
    these queues and map flows to them by setting the relevant fields
162
    (TOS, VLAN PCP).
163
    """
164
165 1
    port = UBInt16()
166
    #: Pad for 64-bit alignment.
167 1
    pad = Pad(6)
168 1
    queue_id = UBInt32()
169
170 1
    _allowed_types = ActionType.OFPAT_ENQUEUE,
171
172 1
    def __init__(self, port=None, queue_id=None):
173
        """The following constructor parameters are optional.
174
175
        Args:
176
            port (physical port or :attr:`.Port.OFPP_IN_PORT`): Queue's port.
177
            queue_id (int): Where to enqueue the packets.
178
        """
179 1
        super().__init__(action_type=ActionType.OFPAT_ENQUEUE, length=16)
180 1
        self.port = port
181 1
        self.queue_id = queue_id
182
183
184 1
class ActionVlanVid(ActionHeader):
185
    """Action structure for :attr:`ActionType.OFPAT_SET_VLAN_VID`.
186
187
    .. note:: The vlan_vid field is 16 bits long,
188
              when an actual VLAN id is only 12 bits.
189
              The value 0xffff is used to indicate that no VLAN id was set
190
    """
191
192 1
    vlan_id = UBInt16()
193
    #: Pad for bit alignment.
194 1
    pad2 = Pad(2)
195
196 1
    _allowed_types = ActionType.OFPAT_SET_VLAN_VID,
197
198 1
    def __init__(self, vlan_id=None):
199
        """The following constructor parameters are optional.
200
201
        Args:
202
            vlan_id (int): VLAN priority.
203
        """
204 1
        super().__init__(action_type=ActionType.OFPAT_SET_VLAN_VID, length=8)
205 1
        self.vlan_id = vlan_id
206
207
208 1
class ActionVlanPCP(ActionHeader):
209
    """Action structure for :attr:`ActionType.OFPAT_SET_VLAN_PCP`."""
210
211 1
    vlan_pcp = UBInt8()
212
    #: Pad for bit alignment.
213 1
    pad = Pad(3)
214
215 1
    _allowed_types = ActionType.OFPAT_SET_VLAN_PCP,
216
217 1
    def __init__(self, vlan_pcp=None):
218
        """The following constructor parameters are optional.
219
220
        Args:
221
            vlan_pcp (int): VLAN Priority.
222
223
        .. note:: The vlan_pcp field is 8 bits long,
224
                  but only the lower 3 bits have meaning.
225
        """
226 1
        super().__init__(action_type=ActionType.OFPAT_SET_VLAN_PCP, length=8)
227 1
        self.vlan_pcp = vlan_pcp
228
229
230 1
class ActionDLAddr(ActionHeader):
231
    """Action structure for :attr:`ActionType.OFPAT_SET_DL_SRC` or _DST."""
232
233 1
    dl_addr = HWAddress()
234
    #: Pad for bit alignment.
235 1
    pad = Pad(6)
236
237 1
    _allowed_types = (ActionType.OFPAT_SET_DL_SRC, ActionType.OFPAT_SET_DL_DST)
238
239 1
    def __init__(self, action_type=None, dl_addr=None):
240
        """The following constructor parameters are optional.
241
242
        Args:
243
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
244
                :attr:`~ActionType.OFPAT_SET_DL_SRC` or
245
                :attr:`~ActionType.OFPAT_SET_DL_DST`.
246
            dl_addr (:class:`~.HWAddress`): Ethernet address.
247
                Defaults to None.
248
        """
249 1
        super().__init__(action_type, length=16)
250 1
        self.dl_addr = dl_addr
251
252
253 1
class ActionNWAddr(ActionHeader):
254
    """Action structure for :attr:`ActionType.OFPAT_SET_NW_SRC` or _DST."""
255
256 1
    nw_addr = UBInt32()
257
258 1
    _allowed_types = (ActionType.OFPAT_SET_NW_SRC, ActionType.OFPAT_SET_NW_DST)
259
260 1
    def __init__(self, action_type=None, nw_addr=None):
261
        """The following constructor parameters are optional.
262
263
        Args:
264
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
265
                :attr:`~ActionType.OFPAT_SET_NW_SRC` or
266
                :attr:`~ActionType.OFPAT_SET_NW_DST`.
267
            nw_addr (int): IP Address.
268
        """
269 1
        super().__init__(action_type, length=8)
270 1
        self.nw_addr = nw_addr
271
272
273 1
class ActionNWTos(ActionHeader):
274
    """Action structure for :attr:`ActionType.OFPAT_SET_NW_TOS`.
275
276
    .. note:: The nw_tos field is the 6 upper bits of the ToS field to set,
277
              in the original bit positions (shifted to the left by 2).
278
    """
279
280 1
    nw_tos = UBInt8()
281
    #: Pad for bit alignment.
282 1
    pad = Pad(3)
283
284 1
    _allowed_types = ActionType.OFPAT_SET_NW_TOS,
285
286 1
    def __init__(self, action_type=None, nw_tos=None):
287
        """The following constructor parameters are optional.
288
289
        Args:
290
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
291
                :attr:`~ActionType.OFPAT_SET_NW_SRC` or
292
                :attr:`~ActionType.OFPAT_SET_NW_DST`.
293
            nw_tos (int): IP ToS (DSCP field, 6 bits).
294
        """
295 1
        super().__init__(action_type, length=8)
296 1
        self.nw_tos = nw_tos
297
298
299 1
class ActionTPPort(ActionHeader):
300
    """Action structure for :attr:`ActionType.OFPAT_SET_TP_SRC` or _DST."""
301
302 1
    tp_port = UBInt16()
303
    #: Pad for bit alignment.
304 1
    pad = Pad(2)
305
306 1
    _allowed_types = (ActionType.OFPAT_SET_TP_SRC, ActionType.OFPAT_SET_TP_DST)
307
308 1
    def __init__(self, action_type=None, tp_port=None):
309
        """The following constructor parameters are optional.
310
311
        Args:
312
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
313
                :attr:`~ActionType.OFPAT_SET_TP_SRC` or
314
                :attr:`~ActionType.OFPAT_SET_TP_DST`.
315
            tp_port (int): TCP/UDP/other port to set.
316
        """
317 1
        super().__init__(action_type, length=8)
318 1
        self.tp_port = tp_port
319
320
321 1
class ActionVendorHeader(ActionHeader):
322
    """Action header for :attr:`ActionType.OFPAT_VENDOR`.
323
324
    The rest of the body is vendor-defined.
325
    """
326
327 1
    vendor = UBInt32()
328
329 1
    _allowed_types = ActionType.OFPAT_VENDOR,
330
331 1
    def __init__(self, length=None, vendor=None):
332
        """The following constructor parameters are optional.
333
334
        Args:
335
            length (int): Length is a multiple of 8.
336
            vender (int): Vendor ID with the same form as in VendorHeader.
337
                Defaults to None.
338
        """
339 1
        super().__init__(action_type=ActionType.OFPAT_VENDOR, length=length)
340 1
        self.vendor = vendor
341
342
343 1
class ListOfActions(FixedTypeList):
344
    """List of actions.
345
346
    Represented by instances of ActionHeader and used on ActionHeader objects.
347
    """
348
349 1
    def __init__(self, items=None):
350
        """The constructor just assigns parameters to object attributes.
351
352
        Args:
353
            items (:class:`~pyof.v0x01.common.action.ActionHeader`):
354
                Instance or a list of instances.
355
        """
356
        super().__init__(pyof_class=ActionHeader, items=items)
357