pyof.v0x04.controller2switch.meter_mod   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 212
Duplicated Lines 0 %

Test Coverage

Coverage 89.47%

Importance

Changes 0
Metric Value
wmc 9
eloc 82
dl 0
loc 212
ccs 68
cts 76
cp 0.8947
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A MeterBandExperimenter.__init__() 0 11 1
A MeterBandDscpRemark.__init__() 0 10 1
A MeterBandHeader.update_length() 0 3 1
A ListOfMeterBandHeader.__init__() 0 7 1
A MeterBandDrop.__init__() 0 8 1
A MeterMod.__init__() 0 17 1
A MeterBandHeader.__init__() 0 13 1
A MeterBandType.find_class() 0 5 1
A MeterBandHeader.unpack() 0 22 1
1
"""Meter modification message."""
2 1
from enum import IntEnum
3
4 1
from pyof.foundation.base import GenericBitMask, GenericMessage
5 1
from pyof.foundation.basic_types import (
6
    FixedTypeList, GenericStruct, Pad, UBInt8, UBInt16, UBInt32)
7 1
from pyof.v0x04.common.header import Header, Type
8
9 1
__all__ = ('MeterMod', 'Meter', 'MeterModCommand', 'MeterFlags',
10
           'MeterBandHeader', 'MeterBandType', 'MeterBandDrop',
11
           'MeterBandDscpRemark', 'MeterBandExperimenter')
12
13
14 1
class Meter(IntEnum):
15
    """Meter numbering. Flow meters can use any number up to OFPM_MAX."""
16
17
    #: Last usable meter.
18 1
    OFPM_MAX = 0xffff0000
19
20
    # Virtual meters.
21
    #: Meter for slow datapath, if any.
22 1
    OFPM_SLOWPATH = 0xfffffffd
23
    #: Meter for controller connection.
24 1
    OFPM_CONTROLLER = 0xfffffffe
25
    #: Represents all meters for stat requests commands.
26 1
    OFPM_ALL = 0xffffffff
27
28
29 1
class MeterModCommand(IntEnum):
30
    """Meter commands."""
31
32
    #: New meter.
33 1
    OFPMC_ADD = 0
34
    #: Modify specified meter.
35 1
    OFPMC_MODIFY = 1
36
    #: Delete specified meter.
37 1
    OFPMC_DELETE = 2
38
39
40 1
class MeterFlags(GenericBitMask):
41
    """Meter configuration flags."""
42
43
    #: Rate value in kb/s (kilo-bit per second).
44 1
    OFPMF_KBPS = 1 << 0
45
    #: Rate value in packet/sec.
46 1
    OFPMF_PKTPS = 1 << 1
47
    #: Do burst size.
48 1
    OFPMF_BURST = 1 << 2
49
    #: Collect statistics.
50 1
    OFPMF_STATS = 1 << 3
51
52
53 1
class MeterBandType(IntEnum):
54
    """Meter band types."""
55
56
    #: Drop packet.
57 1
    OFPMBT_DROP = 1
58
    #: Remark DSCP in the IP header.
59 1
    OFPMBT_DSCP_REMARK = 2
60
    #: Experimenter meter band.
61 1
    OFPMBT_EXPERIMENTER = 0xFFFF
62
63 1
    def find_class(self):
64
        """Return a class related with this type."""
65
        types = {1: MeterBandDrop, 2: MeterBandDscpRemark,
66
                 3: MeterBandExperimenter}
67
        return types[self.value]
68
69
70 1
class MeterBandHeader(GenericStruct):
71
    """Common header for all meter bands."""
72
73 1
    band_type = UBInt16(enum_ref=MeterBandType)
74 1
    length = UBInt16()
75 1
    rate = UBInt32()
76 1
    burst_size = UBInt32()
77
78 1
    def __init__(self, band_type=None, rate=None, burst_size=None):
79
        """Create a MeterBandHeader with the optional parameters below.
80
81
        Args:
82
            band_type (MeterBandType): One of OFPMBT_*.
83
            rate (int): Rate for this band.
84
            burst_size (int): Size of bursts.
85
        """
86 1
        super().__init__()
87 1
        self.band_type = band_type
88 1
        self.rate = rate
89 1
        self.burst_size = burst_size
90 1
        self.update_length()
91
92 1
    def update_length(self):
93
        """Update the length attribute of current instance."""
94 1
        self.length = self.get_size()
95
96 1
    def unpack(self, buff=None, offset=0):
97
        """Unpack *buff* into this object.
98
99
        This method will convert a binary data into a readable value according
100
        to the attribute format.
101
102
        Args:
103
            buff (bytes): Binary buffer.
104
            offset (int): Where to begin unpacking.
105
106
        Raises:
107
            :exc:`~.exceptions.UnpackException`: If unpack fails.
108
109
        """
110
        band_type = UBInt16(enum_ref=MeterBandType)
111
        band_type.unpack(buff, offset)
112
        self.__class__ = MeterBandType(band_type.value).find_class()
113
114
        length = UBInt16()
115
        length.unpack(buff, offset=offset+2)
116
117
        super().unpack(buff[:offset+length.value], offset)
118
119
120 1
class MeterMod(GenericMessage):
121
    """Meter configuration."""
122
123 1
    header = Header(message_type=Type.OFPT_METER_MOD)
124 1
    command = UBInt16(enum_ref=MeterModCommand)
125 1
    flags = UBInt16(enum_ref=MeterFlags)
126 1
    meter_id = UBInt32()
127 1
    bands = FixedTypeList(MeterBandHeader)
128
129 1
    def __init__(self, xid=None, command=None, flags=None, meter_id=None,
130
                 bands=None):
131
        """Create a MeterMod with the optional parameters below.
132
133
        Args:
134
            xid (int): Headers transaction id. Defaults to random.
135
            command (MeterModCommand): One of OFPMC_*.
136
            flags (MeterFlags): One of OFPMF_*.
137
            meter_id (int): Meter instance.
138
            bands (MeterBandHeader): The bands length is inferred from the
139
                length field in the header.
140
        """
141 1
        super().__init__(xid)
142 1
        self.command = command
143 1
        self.flags = flags
144 1
        self.meter_id = meter_id
145 1
        self.bands = bands
146
147
148 1
class MeterBandDrop(MeterBandHeader):
149
    """OFPMBT_DROP band - drop packets."""
150
151 1
    pad = Pad(4)
152
153 1
    def __init__(self, rate=None, burst_size=None):
154
        """Create a MeterBandDrop with the optional parameters below.
155
156
        Args:
157
            rate (int): Rate for dropping packets.
158
            burst_size (int): Size of bursts.
159
        """
160 1
        super().__init__(MeterBandType.OFPMBT_DROP, rate, burst_size)
161
162
163 1
class MeterBandDscpRemark(MeterBandHeader):
164
    """OFPMBT_DSCP_REMARK band - Remark DSCP in the IP header."""
165
166 1
    prec_level = UBInt8()
167 1
    pad = Pad(3)
168
169 1
    def __init__(self, rate=None, burst_size=None, prec_level=None):
170
        """Create a MeterBandDscpRemark with the optional parameters below.
171
172
        Args:
173
            rate (int): Rate for remarking packets.
174
            burst_size (int): Size of bursts.
175
            prec_level (int): Number of precendence level to substract.
176
        """
177 1
        super().__init__(MeterBandType.OFPMBT_DSCP_REMARK, rate, burst_size)
178 1
        self.prec_level = prec_level
179
180
181 1
class MeterBandExperimenter(MeterBandHeader):
182
    """OFPMBT_EXPERIMENTER band - Write actions in action set."""
183
184 1
    experimenter = UBInt32()
185
186 1
    def __init__(self, rate=None, burst_size=None, experimenter=None):
187
        """Create a MeterBandExperimenter with the optional parameters below.
188
189
        Args:
190
            rate (int): Rate for remarking packets.
191
            burst_size (int): Size of bursts.
192
            experimenter (int): Experimenter ID which takes the same form as in
193
                :class:`.ExperimenterHeader`.
194
        """
195 1
        super().__init__(MeterBandType.OFPMBT_EXPERIMENTER, rate, burst_size)
196 1
        self.experimenter = experimenter
197
198
199 1
class ListOfMeterBandHeader(FixedTypeList):
200
    """List of MeterBandHeader.
201
202
    Represented by instances of MeterBandHeader.
203
    """
204
205 1
    def __init__(self, items=None):
206
        """Create a ListOfMeterBandHeader with the optional parameters below.
207
208
        Args:
209
        items (MeterBandHeader): Instance or a list of instances.
210
        """
211
        super().__init__(pyof_class=MeterBandHeader, items=items)
212