AsyncConfig.__init__()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 34
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 10
dl 0
loc 34
ccs 8
cts 8
cp 1
rs 9.9
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
    Char, FixedTypeList, Pad, UBInt8, UBInt16, UBInt32, UBInt64)
9 1
from pyof.foundation.constants import OFP_MAX_TABLE_NAME_LEN
10 1
from pyof.v0x04.asynchronous.flow_removed import FlowRemovedReason
11 1
from pyof.v0x04.asynchronous.packet_in import PacketInReason
12 1
from pyof.v0x04.asynchronous.port_status import PortReason
13
# Local source tree imports
14 1
from pyof.v0x04.common.action import (
15
    ActionHeader, ControllerMaxLen, ListOfActions)
16 1
from pyof.v0x04.common.flow_instructions import ListOfInstruction
17 1
from pyof.v0x04.common.flow_match import ListOfOxmHeader
18 1
from pyof.v0x04.common.header import Header
19 1
from pyof.v0x04.controller2switch.table_mod import Table
20
21 1
__all__ = ('ConfigFlag', 'ControllerRole', 'TableFeaturePropType',
22
           'MultipartType', 'Bucket', 'BucketCounter', 'ListOfBucketCounter',
23
           'ExperimenterMultipartHeader', 'Property', 'InstructionsProperty',
24
           'NextTablesProperty', 'ActionsProperty', 'OxmProperty',
25
           'ListOfProperty', 'TableFeatures')
26
27
# Enum
28
29
30 1
class ConfigFlag(IntEnum):
31
    """Handling of IP fragments."""
32
33
    #: No special handling for fragments.
34 1
    OFPC_FRAG_NORMAL = 0
35
    #: Drop fragments.
36 1
    OFPC_FRAG_DROP = 1
37
    #: Reassemble (only if OFPC_IP_REASM set).
38 1
    OFPC_FRAG_REASM = 2
39 1
    OFPC_FRAG_MASK = 3
40
41
42 1
class ControllerRole(IntEnum):
43
    """Controller roles."""
44
45
    #: Don’t change current role.
46 1
    OFPCR_ROLE_NOCHANGE = 0
47
    #: Default role, full access.
48 1
    OFPCR_ROLE_EQUAL = 1
49
    #: Full access, at most one master.
50 1
    OFPCR_ROLE_MASTER = 2
51
    #: Read-only access.
52 1
    OFPCR_ROLE_SLAVE = 3
53
54
55 1
class TableFeaturePropType(IntEnum):
56
    """Table Property Types.
57
58
    Low order bit cleared indicates a property for a regular Flow Entry.
59
    Low order bit set indicates a property for the Table-Miss Flow Entry.
60
    """
61
62
    # Instructions property.
63 1
    OFPTFPT_INSTRUCTIONS = 0
64
    # Instructions for table-miss.
65 1
    OFPTFPT_INSTRUCTIONS_MISS = 1
66
    # Next Table property.
67 1
    OFPTFPT_NEXT_TABLES = 2
68
    # Next Table for table-miss.
69 1
    OFPTFPT_NEXT_TABLES_MISS = 3
70
    # Write Actions property.
71 1
    OFPTFPT_WRITE_ACTIONS = 4
72
    # Write Actions for table-miss.
73 1
    OFPTFPT_WRITE_ACTIONS_MISS = 5
74
    # Apply Actions property.
75 1
    OFPTFPT_APPLY_ACTIONS = 6
76
    # Apply Actions for table-miss.
77 1
    OFPTFPT_APPLY_ACTIONS_MISS = 7
78
    # Match property.
79 1
    OFPTFPT_MATCH = 8
80
    # Wildcards property.
81 1
    OFPTFPT_WILDCARDS = 10
82
    # Write Set-Field property.
83 1
    OFPTFPT_WRITE_SETFIELD = 12
84
    # Write Set-Field for table-miss.
85 1
    OFPTFPT_WRITE_SETFIELD_MISS = 13
86
    # Apply Set-Field property.
87 1
    OFPTFPT_APPLY_SETFIELD = 14
88
    # Apply Set-Field for table-miss.
89 1
    OFPTFPT_APPLY_SETFIELD_MISS = 15
90
    # Experimenter property.
91 1
    OFPTFPT_EXPERIMENTER = 0xFFFE
92
    # Experimenter for table-miss.
93 1
    OFPTFPT_EXPERIMENTER_MISS = 0xFFFF
94
95
    # pylint: disable=comparison-with-callable
96 1
    def find_class(self):
97
        """Return a class related with this type."""
98
        if self.value <= 1:
99
            return InstructionsProperty
100
        if self.value <= 3:
101
            return NextTablesProperty
102
        if self.value <= 7:
103
            return ActionsProperty
104
105
        return OxmProperty
106
107
108 1
class MultipartType(IntEnum):
109
    """Types of Multipart Messages, both Request and Reply."""
110
111
    #: Description of this OpenFlow switch.
112
    #: The request body is empty.
113
    #: The reply body is struct ofp_desc.
114 1
    OFPMP_DESC = 0
115
116
    #: Individual flow statistics.
117
    #: The request body is struct ofp_flow_stats_request.
118
    #: The reply body is an array of struct ofp_flow_stats.
119 1
    OFPMP_FLOW = 1
120
121
    #: Aggregate flow statistics.
122
    #: The request body is struct ofp_aggregate_stats_request.
123
    #: The reply body is struct ofp_aggregate_stats_reply.
124 1
    OFPMP_AGGREGATE = 2
125
126
    #: Flow table statistics.
127
    #: The request body is empty.
128
    #: The reply body is an array of struct ofp_table_stats.
129 1
    OFPMP_TABLE = 3
130
131
    #: Port statistics.
132
    #: The request body is struct ofp_port_stats_request.
133
    #: The reply body is an array of struct ofp_port_stats.
134 1
    OFPMP_PORT_STATS = 4
135
136
    #: Queue statistics for a port.
137
    #: The request body is struct ofp_queue_stats_request.
138
    #: The reply body is an array of struct ofp_queue_stats.
139 1
    OFPMP_QUEUE = 5
140
141
    #: Group counter statistics.
142
    #: The request body is struct ofp_group_stats_request.
143
    #: The reply is an array of struct ofp_group_stats.
144 1
    OFPMP_GROUP = 6
145
146
    #: Group description.
147
    #: The request body is empty.
148
    #: The reply body is an array of struct ofp_group_desc_stats.
149 1
    OFPMP_GROUP_DESC = 7
150
151
    #: Group features.
152
    #: The request body is empty.
153
    #: The reply body is struct ofp_group_features.
154 1
    OFPMP_GROUP_FEATURES = 8
155
156
    #: Meter statistics.
157
    #: The request body is struct ofp_meter_multipart_requests.
158
    #: The reply body is an array of struct ofp_meter_stats.
159 1
    OFPMP_METER = 9
160
161
    #: Meter configuration.
162
    #: The request body is struct ofp_meter_multipart_requests.
163
    #: The reply body is an array of struct ofp_meter_config.
164 1
    OFPMP_METER_CONFIG = 10
165
166
    #: Meter features.
167
    #: The request body is empty.
168
    #: The reply body is struct ofp_meter_features.
169 1
    OFPMP_METER_FEATURES = 11
170
171
    #: Table features.
172
    #: The request body is either empty or contains an array of
173
    #: struct ofp_table_features containing the controller’s desired view of
174
    #: the switch. If the switch is unable to set the specified view an error
175
    #: is returned.
176
    #: The reply body is an array of struct ofp_table_features.
177 1
    OFPMP_TABLE_FEATURES = 12
178
179
    #: Port description.
180
    #: The request body is empty.
181
    #: The reply body is an array of struct ofp_port.
182 1
    OFPMP_PORT_DESC = 13
183
184
    #: Experimenter extension.
185
    #: The request and reply bodies begin with
186
    #: struct ofp_experimenter_multipart_header.
187
    #: The request and reply bodies are otherwise experimenter-defined.
188 1
    OFPMP_EXPERIMENTER = 0xffff
189
190
191
# Classes
192
193 1
class Bucket(GenericStruct):
194
    """Bucket for use in groups."""
195
196 1
    length = UBInt16()
197 1
    weight = UBInt16()
198 1
    watch_port = UBInt32()
199 1
    watch_group = UBInt32()
200 1
    pad = Pad(4)
201 1
    actions = FixedTypeList(ActionHeader)
202
203 1
    def __init__(self, length=None, weight=None, watch_port=None,
204
                 watch_group=None, actions=None):
205
        """Initialize all instance variables.
206
207
        Args:
208
            length (int): Length the bucket in bytes, including this header and
209
                any padding to make it 64-bit aligned.
210
            weight (int): Relative weight of bucket. Only defined for select
211
                groups.
212
            watch_port (int): Port whose state affects whether this bucket is
213
                live. Only required for fast failover groups.
214
            watch_group (int): Group whose state affects whether this bucket is
215
                live. Only required for fast failover groups.
216
            actions (~pyof.v0x04.common.action.ListOfActions): The action
217
                length is inferred from the length field in the header.
218
219
        """
220 1
        super().__init__()
221 1
        self.length = length
222 1
        self.weight = weight
223 1
        self.watch_port = watch_port
224 1
        self.watch_group = watch_group
225 1
        self.actions = actions
226
227 1
    def __repr__(self):
228
        return f"{type(self).__name__}(actions={self.actions!r})"
229
230 1
    def unpack(self, buff, offset=0):
231
        """Unpack bucket.
232
233
        Bucket has a dynamic content with length as first field.
234
        The length is needed to compute the total buffer offset.
235
        """
236 1
        length = UBInt16()
237 1
        length.unpack(buff, offset=offset)
238 1
        super().unpack(buff[:offset + length.value], offset=offset)
239
240 1
    def get_size(self, value=None):
241
        """
242
        Return the Bucket length.
243
244
        If the object length is None, returns the minimum size.
245
        """
246 1
        if self.length is None:
247 1
            return super().get_size()
248
249 1
        return self.length
250
251
252 1
class BucketCounter(GenericStruct):
253
    """Used in group stats replies."""
254
255
    #: Number of packets processed by bucket.
256 1
    packet_count = UBInt64()
257
    #: Number of bytes processed by bucket.
258 1
    byte_count = UBInt64()
259
260 1
    def __init__(self, packet_count=None, byte_count=None):
261
        """Create BucketCounter with the optional parameters below.
262
263
        Args:
264
            packet_count (int): Number of packets processed by bucket.
265
            byte_count (int): Number of bytes processed by bucket.
266
267
        """
268 1
        super().__init__()
269 1
        self.packet_count = packet_count
270 1
        self.byte_count = byte_count
271
272
273 1
class ListOfBucketCounter(FixedTypeList):
274
    """List of BucketCounter.
275
276
    Represented by instances of BucketCounter.
277
    """
278
279 1
    def __init__(self, items=None):
280
        """Create a ListOfBucketCounter with the optional parameters below.
281
282
        Args:
283
            items (|BucketCounter_v0x04|): Instance or a list of instances.
284
285
        """
286 1
        super().__init__(pyof_class=BucketCounter, items=items)
287
288
289
# Base Classes for other messages - not meant to be directly used, so, because
290
# of that, they will not be inserted on the __all__ attribute.
291
292
293 1
class AsyncConfig(GenericMessage):
294
    """Asynchronous message configuration base class.
295
296
    Common structure for SetAsync and GetAsyncReply messages.
297
298
    AsyncConfig contains three 2-element arrays. Each array controls whether
299
    the controller receives asynchronous messages with a specific
300
    :class:`~pyof.v0x04.common.header.Type`. Within each array, element
301
    0 specifies messages of interest when the controller has a OFPCR_ROLE_EQUAL
302
    or OFPCR_ROLE_MASTER role; element 1, when the controller has a
303
    OFPCR_ROLE_SLAVE role. Each array element is a bit-mask in which a 0-bit
304
    disables receiving a message sent with the reason code corresponding to the
305
    bit index and a 1-bit enables receiving it.
306
    """
307
308
    #: OpenFlow :class:`~pyof.v0x04.common.header.Header`
309
    #: OFPT_GET_ASYNC_REPLY or OFPT_SET_ASYNC.
310 1
    header = Header()
311 1
    packet_in_mask1 = UBInt32(enum_ref=PacketInReason)
312 1
    packet_in_mask2 = UBInt32(enum_ref=PacketInReason)
313 1
    port_status_mask1 = UBInt32(enum_ref=PortReason)
314 1
    port_status_mask2 = UBInt32(enum_ref=PortReason)
315 1
    flow_removed_mask1 = UBInt32(enum_ref=FlowRemovedReason)
316 1
    flow_removed_mask2 = UBInt32(enum_ref=FlowRemovedReason)
317
318 1
    def __init__(self, xid=None, packet_in_mask1=None, packet_in_mask2=None,
319
                 port_status_mask1=None, port_status_mask2=None,
320
                 flow_removed_mask1=None, flow_removed_mask2=None):
321
        """Create a AsyncConfig with the optional parameters below.
322
323
        Args:
324
            xid (int): xid to be used on the message header.
325
            packet_in_mask1
326
                (~pyof.v0x04.asynchronous.packet_in.PacketInReason):
327
                    A instance of PacketInReason
328
            packet_in_mask2
329
                (~pyof.v0x04.asynchronous.packet_in.PacketInReason):
330
                    A instance of PacketInReason
331
            port_status_mask1
332
                (~pyof.v0x04.asynchronous.port_status.PortReason):
333
                    A instance of PortReason
334
            port_status_mask2
335
                (~pyof.v0x04.asynchronous.port_status.PortReason):
336
                    A instance of PortReason
337
            flow_removed_mask1
338
                (~pyof.v0x04.asynchronous.flow_removed.FlowRemoved):
339
                    A instance of FlowRemoved.
340
            flow_removed_mask2
341
                (~pyof.v0x04.asynchronous.flow_removed.FlowRemoved):
342
                    A instance of FlowRemoved.
343
344
        """
345 1
        super().__init__(xid)
346 1
        self.packet_in_mask1 = packet_in_mask1
347 1
        self.packet_in_mask2 = packet_in_mask2
348 1
        self.port_status_mask1 = port_status_mask1
349 1
        self.port_status_mask2 = port_status_mask2
350 1
        self.flow_removed_mask1 = flow_removed_mask1
351 1
        self.flow_removed_mask2 = flow_removed_mask2
352
353
354 1
class RoleBaseMessage(GenericMessage):
355
    """Role basic structure for RoleRequest and RoleReply messages."""
356
357
    #: :class:`~pyof.v0x04.common.header.Header`
358
    #: Type OFPT_ROLE_REQUEST/OFPT_ROLE_REPLY.
359 1
    header = Header()
360
    #: One of NX_ROLE_*. (:class:`~.controller2switch.common.ControllerRole`)
361 1
    role = UBInt32(enum_ref=ControllerRole)
362
    #: Align to 64 bits.
363 1
    pad = Pad(4)
364
    #: Master Election Generation Id.
365 1
    generation_id = UBInt64()
366
367 1
    def __init__(self, xid=None, role=None, generation_id=None):
368
        """Create a RoleBaseMessage with the optional parameters below.
369
370
        Args:
371
            xid (int): OpenFlow xid to the header.
372
            role (:class:`~.controller2switch.common.ControllerRole`): .
373
            generation_id (int): Master Election Generation Id.
374
375
        """
376 1
        super().__init__(xid)
377 1
        self.role = role
378 1
        self.generation_id = generation_id
379
380
381 1
class SwitchConfig(GenericMessage):
382
    """Used as base class for SET_CONFIG and GET_CONFIG_REPLY messages."""
383
384
    #: OpenFlow :class:`~pyof.v0x04.common.header.Header`
385 1
    header = Header()
386 1
    flags = UBInt16(enum_ref=ConfigFlag)
387 1
    miss_send_len = UBInt16()
388
389 1
    def __init__(self, xid=None, flags=ConfigFlag.OFPC_FRAG_NORMAL,
390
                 miss_send_len=ControllerMaxLen.OFPCML_NO_BUFFER):
391
        """Create a SwitchConfig with the optional parameters below.
392
393
        Args:
394
            xid (int): xid to be used on the message header.
395
            flags (ConfigFlag): OFPC_* flags.
396
            miss_send_len (int): UBInt16 max bytes of new flow that the
397
                datapath should send to the controller.
398
399
        """
400 1
        super().__init__(xid)
401 1
        self.flags = flags
402 1
        self.miss_send_len = miss_send_len
403
404
405
# Multipart body
406
407 1
class ExperimenterMultipartHeader(GenericStruct):
408
    """Body for ofp_multipart_request/reply of type OFPMP_EXPERIMENTER."""
409
410 1
    experimenter = UBInt32()
411 1
    exp_type = UBInt32()
412
    #: Followed by experimenter-defined arbitrary data.
413
414 1
    def __init__(self, experimenter=None, exp_type=None):
415
        """Create a ExperimenterMultipartHeader with the parameters below.
416
417
        Args:
418
            experimenter: Experimenter ID which takes the same form as in
419
                struct ofp_experimenter_header (
420
                :class:`~pyof.v0x04.symmetric.experimenter.ExperimenterHeader`)
421
            exp_type: Experimenter defined.
422
423
        """
424
        super().__init__()
425
        self.experimenter = experimenter
426
        self.exp_type = exp_type
427
428
429 1
class Property(GenericStruct):
430
    """Table Property class.
431
432
    This class represents a Table Property generic structure.
433
    """
434
435 1
    property_type = UBInt16(enum_ref=TableFeaturePropType)
436 1
    length = UBInt16(4)
437
438 1
    def __init__(self, property_type=None):
439
        """Create a Property with the optional parameters below.
440
441
        Args:
442
            type(|TableFeaturePropType_v0x04|):
443
                Property Type value of this instance.
444
445
        """
446
        super().__init__()
447
        self.property_type = property_type
448
449 1
    def pack(self, value=None):
450
        """Pack method used to update the length of instance and  packing.
451
452
        Args:
453
            value: Structure to be packed.
454
455
        """
456
        self.update_length()
457
        return super().pack(value)
458
459 1
    def unpack(self, buff=None, offset=0):
460
        """Unpack *buff* into this object.
461
462
        This method will convert a binary data into a readable value according
463
        to the attribute format.
464
465
        Args:
466
            buff (bytes): Binary buffer.
467
            offset (int): Where to begin unpacking.
468
469
        Raises:
470
            :exc:`~.exceptions.UnpackException`: If unpack fails.
471
472
        """
473
        property_type = UBInt16(enum_ref=TableFeaturePropType)
474
        property_type.unpack(buff, offset)
475
        self.__class__ = TableFeaturePropType(property_type.value).find_class()
476
477
        length = UBInt16()
478
        length.unpack(buff, offset=offset+2)
479
        super().unpack(buff[:offset+length.value], offset=offset)
480
481 1
    def update_length(self):
482
        """Update the length of current instance."""
483
        self.length = self.get_size()
484
485
486 1
class InstructionsProperty(Property):
487
    """Instructions property.
488
489
    This class represents Property with the following types:
490
        OFPTFPT_INSTRUCTIONS
491
        OFPTFPT_INSTRUCTIONS_MISS
492
    """
493
494 1
    instruction_ids = ListOfInstruction()
495
496 1
    def __init__(self, property_type=TableFeaturePropType.OFPTFPT_INSTRUCTIONS,
497
                 instruction_ids=None):
498
        """Create a InstructionsProperty with the optional parameters below.
499
500
        Args:
501
            type(|TableFeaturePropType_v0x04|):
502
                Property Type value of this instance.
503
            next_table_ids(|ListOfInstruction_v0x04|):
504
                List of InstructionGotoTable instances.
505
506
        """
507
        super().__init__(property_type=property_type)
508
        self.instruction_ids = instruction_ids if instruction_ids else []
509
        self.update_length()
510
511
512 1
class NextTablesProperty(Property):
513
    """Next Tables Property.
514
515
    This class represents Property with the following types:
516
        OFPTFPT_NEXT_TABLES
517
        OFPTFPT_NEXT_TABLES_MISS
518
    """
519
520 1
    next_table_ids = ListOfInstruction()
521
522 1
    def __init__(self, property_type=TableFeaturePropType.OFPTFPT_NEXT_TABLES,
523
                 next_table_ids=None):
524
        """Create a NextTablesProperty with the optional parameters below.
525
526
        Args:
527
            type(|TableFeaturePropType_v0x04|):
528
                Property Type value of this instance.
529
            next_table_ids (|ListOfInstruction_v0x04|):
530
                List of InstructionGotoTable instances.
531
532
        """
533
        super().__init__(property_type)
534
        self.next_table_ids = (ListOfInstruction() if next_table_ids is None
535
                               else next_table_ids)
536
        self.update_length()
537
538
539 1
class ActionsProperty(Property):
540
    """Actions Property.
541
542
    This class represents Property with the following type:
543
        OFPTFPT_WRITE_ACTIONS
544
        OFPTFPT_WRITE_ACTIONS_MISS
545
        OFPTFPT_APPLY_ACTIONS
546
        OFPTFPT_APPLY_ACTIONS_MISS
547
    """
548
549 1
    action_ids = ListOfActions()
550
551 1
    def __init__(self,
552
                 property_type=TableFeaturePropType.OFPTFPT_WRITE_ACTIONS,
553
                 action_ids=None):
554
        """Create a ActionsProperty with the optional parameters below.
555
556
        Args:
557
            type(|TableFeaturePropType_v0x04|):
558
                Property Type value of this instance.
559
            action_ids(|ListOfActions_v0x04|):
560
                List of Action instances.
561
562
        """
563
        super().__init__(property_type)
564
        self.action_ids = action_ids if action_ids else ListOfActions()
565
        self.update_length()
566
567
568 1
class OxmProperty(Property):
569
    """Match, Wildcard or Set-Field property.
570
571
    This class represents Property with the following types:
572
        OFPTFPT_MATCH
573
        OFPTFPT_WILDCARDS
574
        OFPTFPT_WRITE_SETFIELD
575
        OFPTFPT_WRITE_SETFIELD_MISS
576
        OFPTFPT_APPLY_SETFIELD
577
        OFPTFPT_APPLY_SETFIELD_MISS
578
    """
579
580 1
    oxm_ids = ListOfOxmHeader()
581
582 1
    def __init__(self, property_type=TableFeaturePropType.OFPTFPT_MATCH,
583
                 oxm_ids=None):
584
        """Create an OxmProperty with the optional parameters below.
585
586
        Args:
587
            type(|TableFeaturePropType_v0x04|):
588
                Property Type value of this instance.
589
            oxm_ids(|ListOfOxmHeader_v0x04|):
590
                List of OxmHeader instances.
591
592
        """
593
        super().__init__(property_type)
594
        self.oxm_ids = ListOfOxmHeader() if oxm_ids is None else oxm_ids
595
        self.update_length()
596
597
598 1
class ListOfProperty(FixedTypeList):
599
    """List of Table Property.
600
601
    Represented by instances of Property.
602
    """
603
604 1
    def __init__(self, items=None):
605
        """Create a ListOfProperty with the optional parameters below.
606
607
        Args:
608
            items (|Property_v0x04|): Instance or a list of instances.
609
610
        """
611 1
        super().__init__(pyof_class=Property, items=items)
612
613
614 1
class TableFeatures(GenericStruct):
615
    """Abstraction of common class Table Features.
616
617
    Body for MultipartRequest of type OFPMP_TABLE_FEATURES.
618
    Body of reply to OFPMP_TABLE_FEATURES request.
619
    """
620
621 1
    length = UBInt16()
622
    # /* Identifier of table.  Lower numbered tables are consulted first. */
623 1
    table_id = UBInt8()
624
    # /* Align to 64-bits. */
625 1
    pad = Pad(5)
626 1
    name = Char(length=OFP_MAX_TABLE_NAME_LEN)
627
    # /* Bits of metadata table can match. */
628 1
    metadata_match = UBInt64()
629
    # /* Bits of metadata table can write. */
630 1
    metadata_write = UBInt64()
631
    # /* Bitmap of OFPTC_* values */
632 1
    config = UBInt32()
633
    # /* Max number of entries supported. */
634 1
    max_entries = UBInt32()
635
    # /* Table Feature Property list */
636 1
    properties = ListOfProperty()
637
638 1
    def __init__(self, table_id=Table.OFPTT_ALL, name="",
639
                 metadata_match=0xFFFFFFFFFFFFFFFF,
640
                 metadata_write=0xFFFFFFFFFFFFFFFF,
641
                 config=0,
642
                 max_entries=0,
643
                 properties=None):
644
        """Create a TableFeatures with the optional parameters below.
645
646
        Args:
647
            table_id(int): Indetifier of table.The default value
648
                OFPTT_ALL(``0xff``) will apply the configuration to all tables
649
                in the switch.
650
            name(Char): Characters representing the table name.
651
            metadata_match(int): Indicate the bits of the metadata field that
652
               the table can match on.The default value ``0xFFFFFFFFFFFFFFFF``
653
               indicates that the table can match the full metadata field.
654
            metadata_write(int): Indicates the bits of the metadata field that
655
               the table can write using the OFPIT_WRITE_METADATA instruction.
656
               The default value ``0xFFFFFFFFFFFFFFFF`` indicates that the
657
               table can write the full metadata field.
658
            config(int): Field reseved for future use.
659
            max_entries(int): Describe the maximum number of flow entries that
660
                can be inserted into that table.
661
            properties(~pyof.v0x04.controller2switch.common.ListOfProperty):
662
                List of Property intances.
663
664
        """
665 1
        super().__init__()
666 1
        self.table_id = table_id
667 1
        self.name = name
668 1
        self.metadata_match = metadata_match
669 1
        self.metadata_write = metadata_write
670 1
        self.config = config
671 1
        self.max_entries = max_entries
672 1
        self.properties = (ListOfProperty() if properties is None else
673
                           properties)
674 1
        self.update_length()
675
676 1
    def pack(self, value=None):
677
        """Pack method used to update the length of instance and packing.
678
679
        Args:
680
            value: Structure to be packed.
681
682
        """
683 1
        self.update_length()
684 1
        return super().pack(value)
685
686 1
    def update_length(self):
687
        """Update the length of current instance."""
688 1
        self.length = self.get_size()
689
690 1
    def unpack(self, buff=None, offset=0):
691
        """Unpack *buff* into this object.
692
693
        This method will convert a binary data into a readable value according
694
        to the attribute format.
695
696
        Args:
697
            buff (bytes): Binary buffer.
698
            offset (int): Where to begin unpacking.
699
700
        Raises:
701
            :exc:`~.exceptions.UnpackException`: If unpack fails.
702
703
        """
704 1
        length = UBInt16()
705 1
        length.unpack(buff, offset)
706
        super().unpack(buff[:offset+length.value], offset)
707