Passed
Push — master ( 3643f6...384c84 )
by Diego Rabatone
01:22
created

ActionOutput   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 26
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 1
c 1
b 0
f 0
dl 0
loc 26
ccs 8
cts 8
cp 1
rs 10

1 Method

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 11 1
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', 'ActionStripVlan',
14
           'ActionEnqueue', 'ActionVlanVid', 'ActionVlanPCP', 'ActionDLAddr',
15
           'ActionNWAddr', '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
        """Create an ActionHeader with the optional parameters below.
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
        """
93 1
        self.action_type = UBInt16(enum_ref=ActionType)
94 1
        self.action_type.unpack(buff, offset)
95
96 1
        for cls in ActionHeader.__subclasses__():
97 1
            if self.action_type.value in cls.get_allowed_types():
98 1
                self.__class__ = cls
99 1
                break
100
101 1
        super().unpack(buff, offset)
102
103 1
    @classmethod
104
    def get_allowed_types(cls):
105
        """Return allowed types for the class."""
106 1
        return cls._allowed_types
107
108
109 1
class ActionOutput(ActionHeader):
110
    """Defines the actions output.
111
112
    Action structure for :attr:`ActionType.OFPAT_OUTPUT`, which sends packets
113
    out :attr:`port`. When the :attr:`port` is the
114
    :attr:`.Port.OFPP_CONTROLLER`, :attr:`max_length` indicates the max number
115
    of bytes to send. A :attr:`max_length` of zero means no bytes of the packet
116
    should be sent.
117
    """
118
119 1
    port = UBInt16()
120 1
    max_length = UBInt16()
121
122 1
    _allowed_types = ActionType.OFPAT_OUTPUT,
123
124 1
    def __init__(self, port=None, max_length=UBINT16_MAX_VALUE):
125
        """Create an ActionOutput with the optional parameters below.
126
127
        Args:
128
            port (:class:`~pyof.v0x01.common.phy_port.Port` or :class:`int`):
129
                Output port.
130
            max_length (int): Max length to send to controller.
131
        """
132 1
        super().__init__(action_type=ActionType.OFPAT_OUTPUT, length=8)
133 1
        self.port = port
134 1
        self.max_length = max_length
135
136
137 1
class ActionStripVlan(ActionHeader):
138
    """Strips VLAN information from packets.
139
140
    Action defined for switches to remove the 802.1q VLAN information from
141
    packets.
142
    """
143
144 1
    pad = Pad(4)
145
146 1
    _allowed_types = ActionType.OFPAT_STRIP_VLAN,
147
148 1
    def __init__(self):
149
        """Construct the ActionHeader with the appropriate ActionType.
150
151
        No parameters need to be specified.
152
        """
153
        super().__init__(action_type=ActionType.OFPAT_STRIP_VLAN, length=8)
154
155
156 1
class ActionEnqueue(ActionHeader):
157
    """Send packets to a queue's port.
158
159
    A switch may support only queues that are tied to specific PCP/TOS bits.
160
    In that case, we cannot map an arbitrary flow to a specific queue,
161
    therefore the action ENQUEUE is not supported. The user can still use
162
    these queues and map flows to them by setting the relevant fields
163
    (TOS, VLAN PCP).
164
    """
165
166 1
    port = UBInt16()
167
    #: Pad for 64-bit alignment.
168 1
    pad = Pad(6)
169 1
    queue_id = UBInt32()
170
171 1
    _allowed_types = ActionType.OFPAT_ENQUEUE,
172
173 1
    def __init__(self, port=None, queue_id=None):
174
        """Create an ActionEnqueue with the optional parameters below.
175
176
        Args:
177
            port (physical port or :attr:`.Port.OFPP_IN_PORT`): Queue's port.
178
            queue_id (int): Where to enqueue the packets.
179
        """
180 1
        super().__init__(action_type=ActionType.OFPAT_ENQUEUE, length=16)
181 1
        self.port = port
182 1
        self.queue_id = queue_id
183
184
185 1
class ActionVlanVid(ActionHeader):
186
    """Action structure for :attr:`ActionType.OFPAT_SET_VLAN_VID`.
187
188
    .. note:: The vlan_vid field is 16 bits long,
189
              when an actual VLAN id is only 12 bits.
190
              The value 0xffff is used to indicate that no VLAN id was set
191
    """
192
193 1
    vlan_id = UBInt16()
194
    #: Pad for bit alignment.
195 1
    pad2 = Pad(2)
196
197 1
    _allowed_types = ActionType.OFPAT_SET_VLAN_VID,
198
199 1
    def __init__(self, vlan_id=None):
200
        """Create an ActionVlanVid with the optional parameters below.
201
202
        Args:
203
            vlan_id (int): VLAN priority.
204
        """
205 1
        super().__init__(action_type=ActionType.OFPAT_SET_VLAN_VID, length=8)
206 1
        self.vlan_id = vlan_id
207
208
209 1
class ActionVlanPCP(ActionHeader):
210
    """Action structure for :attr:`ActionType.OFPAT_SET_VLAN_PCP`."""
211
212 1
    vlan_pcp = UBInt8()
213
    #: Pad for bit alignment.
214 1
    pad = Pad(3)
215
216 1
    _allowed_types = ActionType.OFPAT_SET_VLAN_PCP,
217
218 1
    def __init__(self, vlan_pcp=None):
219
        """Create an ActionVlanPCP with the optional parameters below.
220
221
        Args:
222
            vlan_pcp (int): VLAN Priority.
223
224
        .. note:: The vlan_pcp field is 8 bits long,
225
                  but only the lower 3 bits have meaning.
226
        """
227 1
        super().__init__(action_type=ActionType.OFPAT_SET_VLAN_PCP, length=8)
228 1
        self.vlan_pcp = vlan_pcp
229
230
231 1
class ActionDLAddr(ActionHeader):
232
    """Action structure for :attr:`ActionType.OFPAT_SET_DL_SRC` or _DST."""
233
234 1
    dl_addr = HWAddress()
235
    #: Pad for bit alignment.
236 1
    pad = Pad(6)
237
238 1
    _allowed_types = (ActionType.OFPAT_SET_DL_SRC, ActionType.OFPAT_SET_DL_DST)
239
240 1
    def __init__(self, action_type=None, dl_addr=None):
241
        """Create an ActionDLAddr with the optional parameters below.
242
243
        Args:
244
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
245
                :attr:`~ActionType.OFPAT_SET_DL_SRC` or
246
                :attr:`~ActionType.OFPAT_SET_DL_DST`.
247
            dl_addr (:class:`~.HWAddress`): Ethernet address.
248
                Defaults to None.
249
        """
250 1
        super().__init__(action_type, length=16)
251 1
        self.dl_addr = dl_addr
252
253
254 1
class ActionNWAddr(ActionHeader):
255
    """Action structure for :attr:`ActionType.OFPAT_SET_NW_SRC` or _DST."""
256
257 1
    nw_addr = UBInt32()
258
259 1
    _allowed_types = (ActionType.OFPAT_SET_NW_SRC, ActionType.OFPAT_SET_NW_DST)
260
261 1
    def __init__(self, action_type=None, nw_addr=None):
262
        """Create an ActionNWAddr with the optional parameters below.
263
264
        Args:
265
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
266
                :attr:`~ActionType.OFPAT_SET_NW_SRC` or
267
                :attr:`~ActionType.OFPAT_SET_NW_DST`.
268
            nw_addr (int): IP Address.
269
        """
270 1
        super().__init__(action_type, length=8)
271 1
        self.nw_addr = nw_addr
272
273
274 1
class ActionNWTos(ActionHeader):
275
    """Action structure for :attr:`ActionType.OFPAT_SET_NW_TOS`.
276
277
    .. note:: The nw_tos field is the 6 upper bits of the ToS field to set,
278
              in the original bit positions (shifted to the left by 2).
279
    """
280
281 1
    nw_tos = UBInt8()
282
    #: Pad for bit alignment.
283 1
    pad = Pad(3)
284
285 1
    _allowed_types = ActionType.OFPAT_SET_NW_TOS,
286
287 1
    def __init__(self, action_type=None, nw_tos=None):
288
        """Create an ActionNWTos with the optional parameters below.
289
290
        Args:
291
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
292
                :attr:`~ActionType.OFPAT_SET_NW_SRC` or
293
                :attr:`~ActionType.OFPAT_SET_NW_DST`.
294
            nw_tos (int): IP ToS (DSCP field, 6 bits).
295
        """
296 1
        super().__init__(action_type, length=8)
297 1
        self.nw_tos = nw_tos
298
299
300 1
class ActionTPPort(ActionHeader):
301
    """Action structure for :attr:`ActionType.OFPAT_SET_TP_SRC` or _DST."""
302
303 1
    tp_port = UBInt16()
304
    #: Pad for bit alignment.
305 1
    pad = Pad(2)
306
307 1
    _allowed_types = (ActionType.OFPAT_SET_TP_SRC, ActionType.OFPAT_SET_TP_DST)
308
309 1
    def __init__(self, action_type=None, tp_port=None):
310
        """Create an ActionTPPort with the optional parameters below.
311
312
        Args:
313
            action_type (:class:`~pyof.v0x01.common.action.ActionType`):
314
                :attr:`~ActionType.OFPAT_SET_TP_SRC` or
315
                :attr:`~ActionType.OFPAT_SET_TP_DST`.
316
            tp_port (int): TCP/UDP/other port to set.
317
        """
318 1
        super().__init__(action_type, length=8)
319 1
        self.tp_port = tp_port
320
321
322 1
class ActionVendorHeader(ActionHeader):
323
    """Action header for :attr:`ActionType.OFPAT_VENDOR`.
324
325
    The rest of the body is vendor-defined.
326
    """
327
328 1
    vendor = UBInt32()
329
330 1
    _allowed_types = ActionType.OFPAT_VENDOR,
331
332 1
    def __init__(self, length=None, vendor=None):
333
        """Create an ActionVendorHeader with the optional parameters below.
334
335
        Args:
336
            length (int): Length is a multiple of 8.
337
            vender (int): Vendor ID with the same form as in VendorHeader.
338
                Defaults to None.
339
        """
340 1
        super().__init__(action_type=ActionType.OFPAT_VENDOR, length=length)
341 1
        self.vendor = vendor
342
343
344 1
class ListOfActions(FixedTypeList):
345
    """List of actions.
346
347
    Represented by instances of ActionHeader and used on ActionHeader objects.
348
    """
349
350 1
    def __init__(self, items=None):
351
        """Create a ListOfActions with the optional parameters below.
352
353
        Args:
354
            items (:class:`~pyof.v0x01.common.action.ActionHeader`):
355
                Instance or a list of instances.
356
        """
357
        super().__init__(pyof_class=ActionHeader, items=items)
358