Passed
Pull Request — master (#573)
by Gleyberson
02:21
created

AsyncConfig.__init__()   A

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