TableStats.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 24
ccs 9
cts 9
cp 1
rs 9.85
c 0
b 0
f 0
cc 1
nop 8
crap 1

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
"""Defines common structures and enums for controller2switch."""
2
3
# System imports
4 1
from enum import IntEnum
5
6 1
from pyof.foundation.base import GenericMessage, GenericStruct
7 1
from pyof.foundation.basic_types import (
8
    BinaryData, Char, Pad, UBInt8, UBInt16, UBInt32, UBInt64)
9 1
from pyof.foundation.constants import (
10
    DESC_STR_LEN, OFP_MAX_TABLE_NAME_LEN, SERIAL_NUM_LEN)
11
# Local source tree imports
12 1
from pyof.v0x01.common.action import ListOfActions
13 1
from pyof.v0x01.common.flow_match import FlowWildCards, Match
14 1
from pyof.v0x01.common.header import Header
15 1
from pyof.v0x01.common.phy_port import Port
16
17
# Third-party imports
18
19 1
__all__ = ('ConfigFlag', 'StatsType', 'AggregateStatsReply',
20
           'AggregateStatsRequest', 'DescStats', 'FlowStats',
21
           'FlowStatsRequest', 'PortStats', 'PortStatsRequest', 'QueueStats',
22
           'QueueStatsRequest', 'TableStats', 'VendorStats',
23
           'VendorStatsRequest')
24
25
# Enums
26
27
28 1
class ConfigFlag(IntEnum):
29
    """Configuration Flags. Handling of IP Fragments."""
30
31
    #: No special handling for fragments
32 1
    OFPC_FRAG_NORMAL = 0
33
    #: Drop fragments
34 1
    OFPC_FRAG_DROP = 1
35
    #: Reassemble (only if OFPC_IP_REASM set)
36 1
    OFPC_FRAG_REASM = 2
37 1
    OFPC_FRAG_MASK = 3
38
39
40 1
class StatsType(IntEnum):
41
    """Type field to be used both in both request and reply.
42
43
    It specifies the kind of information being passed and determines how the
44
    body field is interpreted.
45
    """
46
47
    #: Description of this OpenFlow switch. The request body is empty.
48 1
    OFPST_DESC = 0
49
    #: Individual flow statistics. The request body is struct
50
    #: ofp_flow_stats_request.
51 1
    OFPST_FLOW = 1
52
    #: Aggregate flow statistics. The request body is struct
53
    #: ofp_aggregate_stats_request.
54 1
    OFPST_AGGREGATE = 2
55
    #: Flow table statistics. The request body is empty.
56 1
    OFPST_TABLE = 3
57
    #: Physical port statistics. The request body is empty.
58 1
    OFPST_PORT = 4
59
    #: Queue statistics for a port. The request body defines the port
60 1
    OFPST_QUEUE = 5
61
    #: Vendor extension. The request and reply bodies begin with a 32-bit
62
    #: vendor ID
63 1
    OFPST_VENDOR = 0xffff
64
65
66
# Classes
67
68
69 1
class SwitchConfig(GenericMessage):
70
    """Used as base class for SET_CONFIG and GET_CONFIG_REPLY messages."""
71
72 1
    header = Header()
73 1
    flags = UBInt16(enum_ref=ConfigFlag)
74 1
    miss_send_len = UBInt16()
75
76 1
    def __init__(self, xid=None, flags=None, miss_send_len=None):
77
        """Create a SwitchConfig with the optional parameters below.
78
79
        Args:
80
            xid (int): xid to be used on the message header.
81
            flags (ConfigFlag): OFPC_* flags.
82
            miss_send_len (int): UBInt16 max bytes of new flow that the
83
                datapath should send to the controller.
84
        """
85 1
        super().__init__(xid)
86 1
        self.flags = flags
87 1
        self.miss_send_len = miss_send_len
88
89 1
    def __repr__(self):
90
        """Show a full representation of the object."""
91
        return "%s(xid=%r, flags=%s, miss_send_len=%r)" \
92
               % (self.__class__.__name__, self.header.xid, self.flags,
93
                  self.miss_send_len)
94
95
96 1
class AggregateStatsReply(GenericStruct):
97
    """Body of reply to OFPST_AGGREGATE request."""
98
99 1
    packet_count = UBInt64()
100 1
    byte_count = UBInt64()
101 1
    flow_count = UBInt32()
102
    #: Align to 64 bits
103 1
    pad = Pad(4)
104
105 1
    def __init__(self, packet_count=None, byte_count=None, flow_count=None):
106
        """Create a AggregateStatsReply with the optional parameters below.
107
108
        Args:
109
            packet_count (int): Number of packets in flows
110
            byte_count (int):   Number of bytes in flows
111
            flow_count (int):   Number of flows
112
        """
113 1
        super().__init__()
114 1
        self.packet_count = packet_count
115 1
        self.byte_count = byte_count
116 1
        self.flow_count = flow_count
117
118
119 1
class AggregateStatsRequest(GenericStruct):
120
    """Body for ofp_stats_request of type OFPST_AGGREGATE."""
121
122 1
    match = Match()
123 1
    table_id = UBInt8()
124
    #: Align to 32 bits
125 1
    pad = Pad(1)
126 1
    out_port = UBInt16()
127
128 1
    def __init__(self, match=Match(), table_id=0xff, out_port=Port.OFPP_NONE):
129
        """Create a AggregateStatsRequest with the optional parameters below.
130
131
        Args:
132
            match (~pyof.v0x01.common.flow_match.Match): Fields to match.
133
            table_id (int): ID of table to read (from pyof_table_stats) 0xff
134
                for all tables or 0xfe for emergency.
135
            out_port (int): Require matching entries to include this as an
136
                output port. A value of OFPP_NONE indicates no restriction.
137
        """
138 1
        super().__init__()
139 1
        self.match = match
140 1
        self.table_id = table_id
141 1
        self.out_port = out_port
142
143
144 1 View Code Duplication
class DescStats(GenericStruct):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
145
    """Information available from the OFPST_DESC stats request.
146
147
    Information about the switch manufacturer, hardware revision, software
148
    revision, serial number and a description field.
149
    """
150
151 1
    mfr_desc = Char(length=DESC_STR_LEN)
152 1
    hw_desc = Char(length=DESC_STR_LEN)
153 1
    sw_desc = Char(length=DESC_STR_LEN)
154 1
    serial_num = Char(length=SERIAL_NUM_LEN)
155 1
    dp_desc = Char(length=DESC_STR_LEN)
156
157 1
    def __init__(self, mfr_desc=None, hw_desc=None, sw_desc=None,
158
                 serial_num=None, dp_desc=None):
159
        """Create a DescStats with the optional parameters below.
160
161
        Args:
162
            mfr_desc (str): Manufacturer description
163
            hw_desc (str): Hardware description
164
            sw_desc (str): Software description
165
            serial_num (str): Serial number
166
            dp_desc (str): Human readable description of datapath
167
        """
168 1
        super().__init__()
169 1
        self.mfr_desc = mfr_desc
170 1
        self.hw_desc = hw_desc
171 1
        self.sw_desc = sw_desc
172 1
        self.serial_num = serial_num
173 1
        self.dp_desc = dp_desc
174
175
176 1 View Code Duplication
class FlowStats(GenericStruct):
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
177
    """Body of reply to OFPST_FLOW request."""
178
179 1
    length = UBInt16()
180 1
    table_id = UBInt8()
181
    #: Align to 32 bits.
182 1
    pad = Pad(1)
183 1
    match = Match()
184 1
    duration_sec = UBInt32()
185 1
    duration_nsec = UBInt32()
186 1
    priority = UBInt16()
187 1
    idle_timeout = UBInt16()
188 1
    hard_timeout = UBInt16()
189
    #: Align to 64-bits
190 1
    pad2 = Pad(6)
191 1
    cookie = UBInt64()
192 1
    packet_count = UBInt64()
193 1
    byte_count = UBInt64()
194 1
    actions = ListOfActions()
195
196 1
    def __init__(self, length=None, table_id=None, match=None,
197
                 duration_sec=None, duration_nsec=None, priority=None,
198
                 idle_timeout=None, hard_timeout=None, cookie=None,
199
                 packet_count=None, byte_count=None, actions=None):
200
        """Create a FlowStats with the optional parameters below.
201
202
        Args:
203
            length (int): Length of this entry.
204
            table_id (int): ID of table flow came from.
205
            match (~pyof.v0x01.common.flow_match.Match): Description of fields.
206
            duration_sec (int): Time flow has been alive in seconds.
207
            duration_nsec (int): Time flow has been alive in nanoseconds in
208
                addition to duration_sec.
209
            priority (int): Priority of the entry. Only meaningful when this
210
                is not an exact-match entry.
211
            idle_timeout (int): Number of seconds idle before expiration.
212
            hard_timeout (int): Number of seconds before expiration.
213
            cookie (int): Opaque controller-issued identifier.
214
            packet_count (int): Number of packets in flow.
215
            byte_count (int): Number of bytes in flow.
216
            actions (:class:`~pyof.v0x01.common.actions.ListOfActions`):
217
                List of Actions.
218
        """
219 1
        super().__init__()
220 1
        self.length = length
221 1
        self.table_id = table_id
222 1
        self.match = match
223 1
        self.duration_sec = duration_sec
224 1
        self.duration_nsec = duration_nsec
225 1
        self.priority = priority
226 1
        self.idle_timeout = idle_timeout
227 1
        self.hard_timeout = hard_timeout
228 1
        self.cookie = cookie
229 1
        self.packet_count = packet_count
230 1
        self.byte_count = byte_count
231 1
        self.actions = [] if actions is None else actions
232
233 1
    def unpack(self, buff, offset=0):
234
        """Unpack *buff* into this object.
235
236
        Do nothing, since the _length is already defined and it is just a Pad.
237
        Keep buff and offset just for compability with other unpack methods.
238
239
        Args:
240
            buff (bytes): Buffer where data is located.
241
            offset (int): Where data stream begins.
242
        """
243 1
        self.length = UBInt16()
244 1
        self.length.unpack(buff, offset)
245 1
        max_length = offset + self.length.value
246 1
        super().unpack(buff[:max_length], offset)
247
248
249 1
class FlowStatsRequest(GenericStruct):
250
    """Body for ofp_stats_request of type OFPST_FLOW."""
251
252 1
    match = Match()
253 1
    table_id = UBInt8()
254
    #: Align to 32 bits.
255 1
    pad = Pad(1)
256 1
    out_port = UBInt16()
257
258 1
    def __init__(self, match=None, table_id=0xff, out_port=Port.OFPP_NONE):
259
        """Create a FlowStatsRequest with the optional parameters below.
260
261
        Args:
262
            match (:class:`~pyof.v0x01.common.flow_match.Match`):
263
                Fields to match.
264
            table_id (int): ID of table to read (from pyof_table_stats)
265
                0xff for all tables or 0xfe for emergency.
266
            out_port (:class:`int`, :class:`~pyof.v0x01.common.phy_port.Port`):
267
                Require matching entries to include this as an output port.
268
                A value of :attr:`.Port.OFPP_NONE` indicates no restriction.
269
        """
270 1
        super().__init__()
271 1
        self.match = Match() if match is None else match
272 1
        self.table_id = table_id
273 1
        self.out_port = out_port
274
275
276 1
class PortStats(GenericStruct):
277
    """Body of reply to OFPST_PORT request.
278
279
    If a counter is unsupported, set the field to all ones.
280
    """
281
282 1
    port_no = UBInt16()
283
    #: Align to 64-bits.
284 1
    pad = Pad(6)
285 1
    rx_packets = UBInt64()
286 1
    tx_packets = UBInt64()
287 1
    rx_bytes = UBInt64()
288 1
    tx_bytes = UBInt64()
289 1
    rx_dropped = UBInt64()
290 1
    tx_dropped = UBInt64()
291 1
    rx_errors = UBInt64()
292 1
    tx_errors = UBInt64()
293 1
    rx_frame_err = UBInt64()
294 1
    rx_over_err = UBInt64()
295 1
    rx_crc_err = UBInt64()
296 1
    collisions = UBInt64()
297
298 1
    def __init__(self, port_no=None, rx_packets=None,
299
                 tx_packets=None, rx_bytes=None, tx_bytes=None,
300
                 rx_dropped=None, tx_dropped=None, rx_errors=None,
301
                 tx_errors=None, rx_frame_err=None, rx_over_err=None,
302
                 rx_crc_err=None, collisions=None):
303
        """Create a PortStats with the optional parameters below.
304
305
        Args:
306
            port_no (:class:`int`, :class:`~pyof.v0x01.common.phy_port.Port`):
307
                Port number.
308
            rx_packets (int): Number of received packets.
309
            tx_packets (int): Number of transmitted packets.
310
            rx_bytes (int): Number of received bytes.
311
            tx_bytes (int): Number of transmitted bytes.
312
            rx_dropped (int): Number of packets dropped by RX.
313
            tx_dropped (int): Number of packets dropped by TX.
314
            rx_errors (int): Number of receive errors. This is a super-set of
315
                more specific receive errors and should be greater than or
316
                equal to the sum of all rx_*_err values.
317
            tx_errors (int): Number of transmit errors.  This is a super-set of
318
                more specific transmit errors and should be greater than or
319
                equal to the sum of all tx_*_err values (none currently
320
                defined).
321
            rx_frame_err (int): Number of frame alignment errors.
322
            rx_over_err (int): Number of packets with RX overrun.
323
            rx_crc_err (int): Number of CRC errors.
324
            collisions (int): Number of collisions.
325
        """
326 1
        super().__init__()
327 1
        self.port_no = port_no
328 1
        self.rx_packets = rx_packets
329 1
        self.tx_packets = tx_packets
330 1
        self.rx_bytes = rx_bytes
331 1
        self.tx_bytes = tx_bytes
332 1
        self.rx_dropped = rx_dropped
333 1
        self.tx_dropped = tx_dropped
334 1
        self.rx_errors = rx_errors
335 1
        self.tx_errors = tx_errors
336 1
        self.rx_frame_err = rx_frame_err
337 1
        self.rx_over_err = rx_over_err
338 1
        self.rx_crc_err = rx_crc_err
339 1
        self.collisions = collisions
340
341
342 1
class PortStatsRequest(GenericStruct):
343
    """Body for ofp_stats_request of type OFPST_PORT."""
344
345 1
    port_no = UBInt16()
346
    #: Align to 64-bits.
347 1
    pad = Pad(6)
348
349 1
    def __init__(self, port_no=Port.OFPP_NONE):
350
        """Create a PortStatsRequest with the optional parameters below.
351
352
        Args:
353
            port_no (:class:`int`, :class:`~pyof.v0x01.common.phy_port.Port`):
354
                OFPST_PORT message must request statistics either for a single
355
                port (specified in ``port_no``) or for all ports
356
                (if ``port_no`` == :attr:`.Port.OFPP_NONE`).
357
        """
358 1
        super().__init__()
359 1
        self.port_no = port_no
360
361
362 1
class QueueStats(GenericStruct):
363
    """Implements the reply body of a port_no."""
364
365 1
    port_no = UBInt16()
366
    #: Align to 32-bits.
367 1
    pad = Pad(2)
368 1
    queue_id = UBInt32()
369 1
    tx_bytes = UBInt64()
370 1
    tx_packets = UBInt64()
371 1
    tx_errors = UBInt64()
372
373 1
    def __init__(self, port_no=None, queue_id=None, tx_bytes=None,
374
                 tx_packets=None, tx_errors=None):
375
        """Create a QueueStats with the optional parameters below.
376
377
        Args:
378
            port_no (:class:`int`, :class:`~pyof.v0x01.common.phy_port.Port`):
379
                Port Number.
380
            queue_id (int): Queue ID.
381
            tx_bytes (int): Number of transmitted bytes.
382
            tx_packets (int): Number of transmitted packets.
383
            tx_errors (int): Number of packets dropped due to overrun.
384
        """
385 1
        super().__init__()
386 1
        self.port_no = port_no
387 1
        self.queue_id = queue_id
388 1
        self.tx_bytes = tx_bytes
389 1
        self.tx_packets = tx_packets
390 1
        self.tx_errors = tx_errors
391
392
393 1
class QueueStatsRequest(GenericStruct):
394
    """Implements the request body of a ``port_no``."""
395
396 1
    port_no = UBInt16()
397
    #: Align to 32-bits
398 1
    pad = Pad(2)
399 1
    queue_id = UBInt32()
400
401 1
    def __init__(self, port_no=None, queue_id=None):
402
        """Create a QueueStatsRequest with the optional parameters below.
403
404
        Args:
405
            port_no (:class:`int`, :class:`~pyof.v0x01.common.phy_port.Port`):
406
                 All ports if :attr:`.Port.OFPP_ALL`.
407
            queue_id (int): All queues if OFPQ_ALL (``0xfffffff``).
408
        """
409 1
        super().__init__()
410 1
        self.port_no = port_no
411 1
        self.queue_id = queue_id
412
413
414 1
class TableStats(GenericStruct):
415
    """Body of reply to OFPST_TABLE request."""
416
417 1
    table_id = UBInt8()
418
    #: Align to 32-bits.
419 1
    pad = Pad(3)
420 1
    name = Char(length=OFP_MAX_TABLE_NAME_LEN)
421 1
    wildcards = UBInt32(enum_ref=FlowWildCards)
422 1
    max_entries = UBInt32()
423 1
    active_count = UBInt32()
424 1
    count_lookup = UBInt64()
425 1
    count_matched = UBInt64()
426
427 1
    def __init__(self, table_id=None, name=None, wildcards=None,
428
                 max_entries=None, active_count=None, count_lookup=None,
429
                 count_matched=None):
430
        """Create a TableStats with the optional parameters below.
431
432
        Args:
433
            table_id (int): Identifier of table.  Lower numbered tables are
434
                consulted first.
435
            name (str): Table name.
436
            wildcards (:class:`~pyof.v0x01.common.flow_match.FlowWildCards`):
437
                Bitmap of OFPFW_* wildcards that are supported by the table.
438
            max_entries (int): Max number of entries supported.
439
            active_count (int): Number of active entries.
440
            count_lookup (int): Number of packets looked up in table.
441
            count_matched (int): Number of packets that hit table.
442
        """
443 1
        super().__init__()
444 1
        self.table_id = table_id
445 1
        self.name = name
446 1
        self.wildcards = wildcards
447 1
        self.max_entries = max_entries
448 1
        self.active_count = active_count
449 1
        self.count_lookup = count_lookup
450 1
        self.count_matched = count_matched
451
452
453 1
class VendorStats(GenericStruct):
454
    """Vendor extension."""
455
456 1
    vendor = UBInt32()
457 1
    body = BinaryData()
458
459 1
    def __init__(self, vendor=None, body=b''):
460
        """Create instance attributes.
461
462
        Args:
463
            vendor (int): 32-bit vendor ID.
464
            body (bytes): Vendor-defined body
465
        """
466 1
        super().__init__()
467 1
        self.vendor = vendor
468 1
        self.body = body
469
470
471
VendorStatsRequest = VendorStats
472