Completed
Push — master ( 58d110...b766aa )
by Carlos Eduardo
12s
created

ActionStripVlan   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 17
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

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

1 Method

Rating   Name   Duplication   Size   Complexity  
A __init__() 0 6 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', 'ActionEnqueue',
14
           'ActionVlanVid', 'ActionVlanPCP', 'ActionDLAddr', 'ActionNWAddr',
15
           'ActionNWTos', 'ActionTPPort', 'ActionVendorHeader',
16
           'ListOfActions')
17
18
# Enums
19
20 1
21
class ActionType(GenericBitMask):
22
    """Actions associated with flows and packets."""
23
24 1
    #: Output to switch port.
25
    OFPAT_OUTPUT = 0
26 1
    #: Set the 802.1q VLAN id.
27
    OFPAT_SET_VLAN_VID = 1
28 1
    #: Set the 802.1q priority.
29
    OFPAT_SET_VLAN_PCP = 2
30 1
    #: Strip the 802.1q header.
31
    OFPAT_STRIP_VLAN = 3
32 1
    #: Ethernet source address.
33
    OFPAT_SET_DL_SRC = 4
34 1
    #: Ethernet destination address.
35
    OFPAT_SET_DL_DST = 5
36 1
    #: IP source address.
37
    OFPAT_SET_NW_SRC = 6
38 1
    #: IP destination address.
39
    OFPAT_SET_NW_DST = 7
40 1
    #: IP ToS (DSCP field, 6 bits).
41
    OFPAT_SET_NW_TOS = 8
42 1
    #: TCP/UDP source port.
43
    OFPAT_SET_TP_SRC = 9
44 1
    #: TCP/UDP destination port.
45
    OFPAT_SET_TP_DST = 10
46 1
    #: Output to queue.
47
    OFPAT_ENQUEUE = 11
48 1
    #: Vendor specific.
49
    OFPAT_VENDOR = 0xffff
50
51
52
# Classes
53
54 1
55
class ActionHeader(GenericStruct):
56
    """Defines the Header that is common to all actions."""
57 1
58 1
    action_type = UBInt16(enum_ref=ActionType)
59
    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 1
65
    _allowed_types = ()
66 1
67
    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 1
            length (int): Length of action, including this header.
74 1
        """
75 1
        super().__init__()
76
        self.action_type = action_type
77 1
        self.length = length
78
79
    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 1
            Exception: If there is a struct unpacking error.
91 1
        """
92
        self.action_type = UBInt16(enum_ref=ActionType)
93 1
        self.action_type.unpack(buff, offset)
94 1
95 1
        for cls in ActionHeader.__subclasses__():
96 1
            if self.action_type.value in cls.get_allowed_types():
97
                self.__class__ = cls
98 1
                break
99
100 1
        super().unpack(buff, offset)
101
102
    @classmethod
103 1
    def get_allowed_types(cls):
104
        """Return allowed types for the class."""
105
        return cls._allowed_types
106 1
107
108
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 1
    """
117 1
118
    port = UBInt16()
119 1
    max_length = UBInt16()
120
121 1
    _allowed_types = ActionType.OFPAT_OUTPUT,
122
123
    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 1
                Output port.
129 1
            max_length (int): Max length to send to controller.
130 1
        """
131
        super().__init__(action_type=ActionType.OFPAT_OUTPUT, length=8)
132
        self.port = port
133 1
        self.max_length = max_length
134
135
136
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 1
147
    def __init__(self):
148 1
        """Construct the ActionHeader with the appropriate ActionType.
149
150 1
        No parameters need to be specified.
151
        """
152
        super().__init__(action_type=ActionType.OFPAT_STRIP_VLAN, length=8)
153
154
155
class ActionEnqueue(ActionHeader):
156
    """Send packets to a queue's port.
157 1
158 1
    A switch may support only queues that are tied to specific PCP/TOS bits.
159 1
    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 1
    (TOS, VLAN PCP).
163
    """
164
165
    port = UBInt16()
166
    #: Pad for 64-bit alignment.
167
    pad = Pad(6)
168
    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 1
175
        Args:
176 1
            port (physical port or :attr:`.Port.OFPP_IN_PORT`): Queue's port.
177
            queue_id (int): Where to enqueue the packets.
178
        """
179
        super().__init__(action_type=ActionType.OFPAT_ENQUEUE, length=16)
180
        self.port = port
181
        self.queue_id = queue_id
182 1
183 1
184
class ActionVlanVid(ActionHeader):
185
    """Action structure for :attr:`ActionType.OFPAT_SET_VLAN_VID`.
186 1
187
    .. note:: The vlan_vid field is 16 bits long,
188
              when an actual VLAN id is only 12 bits.
189 1
              The value 0xffff is used to indicate that no VLAN id was set
190
    """
191 1
192
    vlan_id = UBInt16()
193 1
    #: Pad for bit alignment.
194
    pad2 = Pad(2)
195 1
196
    _allowed_types = ActionType.OFPAT_SET_VLAN_VID,
197
198
    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
    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 1
                :attr:`~ActionType.OFPAT_SET_DL_DST`.
246 1
            dl_addr (:class:`~.HWAddress`): Ethernet address.
247
                Defaults to None.
248
        """
249 1
        super().__init__(action_type, length=16)
250
        self.dl_addr = dl_addr
251
252
253
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 1
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
        super().__init__(action_type, length=8)
270 1
        self.nw_addr = nw_addr
271 1
272
273
class ActionNWTos(ActionHeader):
274 1
    """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 1
              in the original bit positions (shifted to the left by 2).
278
    """
279 1
280
    nw_tos = UBInt8()
281 1
    #: Pad for bit alignment.
282
    pad = Pad(3)
283 1
284
    _allowed_types = ActionType.OFPAT_SET_NW_TOS,
285
286
    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 1
                :attr:`~ActionType.OFPAT_SET_NW_SRC` or
292 1
                :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
        self.nw_tos = nw_tos
297
298
299
class ActionTPPort(ActionHeader):
300
    """Action structure for :attr:`ActionType.OFPAT_SET_TP_SRC` or _DST."""
301 1
302
    tp_port = UBInt16()
303 1
    #: Pad for bit alignment.
304
    pad = Pad(2)
305 1
306
    _allowed_types = (ActionType.OFPAT_SET_TP_SRC, ActionType.OFPAT_SET_TP_DST)
307
308
    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 1
                :attr:`~ActionType.OFPAT_SET_TP_SRC` or
314 1
                :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
        self.tp_port = tp_port
319
320
321
class ActionVendorHeader(ActionHeader):
322
    """Action header for :attr:`ActionType.OFPAT_VENDOR`.
323 1
324
    The rest of the body is vendor-defined.
325
    """
326
327
    vendor = UBInt32()
328
329 1
    _allowed_types = ActionType.OFPAT_VENDOR,
330
331
    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
        super().__init__(action_type=ActionType.OFPAT_VENDOR, length=length)
340
        self.vendor = vendor
341
342
343
class ListOfActions(FixedTypeList):
344
    """List of actions.
345
346
    Represented by instances of ActionHeader and used on ActionHeader objects.
347
    """
348
349
    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