Passed
Push — master ( 0109ea...ebaa29 )
by Beraldo
03:37
created

ListOfBucketCounter.__init__()   A

Complexity

Conditions 1

Size

Total Lines 8
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 8
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nop 2
crap 1
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