summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYAMAMOTO Takashi <yamamoto@valinux.co.jp>2013-07-02 11:13:47 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2013-07-12 06:49:21 +0900
commit309e9c688ca6b80f7a666c6909119fcd1e47e11e (patch)
treeb3717f10275c3ad31eb861a6d120f26819b8e83c
parentfbc7bafe01020962b8fbb3997937732a0320630c (diff)
of1.3: of-wire json adapt
Signed-off-by: YAMAMOTO Takashi <yamamoto@valinux.co.jp> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--ryu/ofproto/ofproto_v1_3.py12
-rw-r--r--ryu/ofproto/ofproto_v1_3_parser.py452
2 files changed, 286 insertions, 178 deletions
diff --git a/ryu/ofproto/ofproto_v1_3.py b/ryu/ofproto/ofproto_v1_3.py
index 0b0af463..17cef2b8 100644
--- a/ryu/ofproto/ofproto_v1_3.py
+++ b/ryu/ofproto/ofproto_v1_3.py
@@ -1046,6 +1046,18 @@ def oxm_tlv_header_w(field, length):
return _oxm_tlv_header(OFPXMC_OPENFLOW_BASIC, field, 1, length * 2)
+def oxm_tlv_header_extract_hasmask(header):
+ return (header >> 8) & 1
+
+
+def oxm_tlv_header_extract_length(header):
+ if oxm_tlv_header_extract_hasmask(header):
+ length = (header & 0xff) / 2
+ else:
+ length = header & 0xff
+ return length
+
+
OXM_OF_IN_PORT = oxm_tlv_header(OFPXMT_OFB_IN_PORT, 4)
OXM_OF_IN_PHY_PORT = oxm_tlv_header(OFPXMT_OFB_IN_PHY_PORT, 4)
OXM_OF_METADATA = oxm_tlv_header(OFPXMT_OFB_METADATA, 8)
diff --git a/ryu/ofproto/ofproto_v1_3_parser.py b/ryu/ofproto/ofproto_v1_3_parser.py
index 03814693..060b8267 100644
--- a/ryu/ofproto/ofproto_v1_3_parser.py
+++ b/ryu/ofproto/ofproto_v1_3_parser.py
@@ -14,13 +14,12 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-import collections
import struct
import itertools
from ryu.lib import mac
from ryu import utils
-from ofproto_parser import MsgBase, msg_pack_into, msg_str_attr
+from ofproto_parser import StringifyMixin, MsgBase, msg_pack_into, msg_str_attr
from . import ofproto_parser
from . import ofproto_v1_3
@@ -54,9 +53,9 @@ def msg_parser(datapath, version, msg_type, msg_len, xid, buf):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_HELLO)
class OFPHello(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, elements=[]):
super(OFPHello, self).__init__(datapath)
- self.elements = None
+ self.elements = elements
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -81,12 +80,12 @@ class OFPHello(MsgBase):
return msg
-class OFPHelloElemVersionBitmap(object):
+class OFPHelloElemVersionBitmap(StringifyMixin):
def __init__(self, versions):
super(OFPHelloElemVersionBitmap, self).__init__()
- self.type = ofproto_v1_3.OFPHET_VERSIONBITMAP
- self.length = None
- self.bitmaps = None
+ self._type = ofproto_v1_3.OFPHET_VERSIONBITMAP
+ self._length = None
+ self._bitmaps = None
self.versions = versions
@classmethod
@@ -110,19 +109,19 @@ class OFPHelloElemVersionBitmap(object):
for i, bitmap in enumerate(bitmaps)
for shift in range(31) if bitmap & (1 << shift)]
elem = cls(versions)
- elem.length = length
- elem.bitmaps = bitmaps
+ elem._length = length
+ elem._bitmaps = bitmaps
return elem
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_ERROR)
class OFPErrorMsg(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, type_=None, code=None, data=None):
super(OFPErrorMsg, self).__init__(datapath)
- self.type = None
- self.code = None
- self.data = None
+ self.type = type_
+ self.code = code
+ self.data = data
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -144,9 +143,9 @@ class OFPErrorMsg(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_ECHO_REQUEST)
class OFPEchoRequest(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, data=None):
super(OFPEchoRequest, self).__init__(datapath)
- self.data = None
+ self.data = data
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -163,9 +162,9 @@ class OFPEchoRequest(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_ECHO_REPLY)
class OFPEchoReply(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, data=None):
super(OFPEchoReply, self).__init__(datapath)
- self.data = None
+ self.data = data
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -182,10 +181,11 @@ class OFPEchoReply(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_EXPERIMENTER)
class OFPExperimenter(MsgBase):
- def __init__(self, datapath, experimenter=None, exp_type=None):
+ def __init__(self, datapath, experimenter=None, exp_type=None, data=None):
super(OFPExperimenter, self).__init__(datapath)
self.experimenter = experimenter
self.exp_type = exp_type
+ self.data = data
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -209,8 +209,14 @@ class OFPFeaturesRequest(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_FEATURES_REPLY)
class OFPSwitchFeatures(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, datapath_id=None, n_buffers=None,
+ n_tables=None, auxiliary_id=None, capabilities=None):
super(OFPSwitchFeatures, self).__init__(datapath)
+ self.datapath_id = datapath_id
+ self.n_buffers = n_buffers
+ self.n_tables = n_tables
+ self.auxiliary_id = auxiliary_id
+ self.capabilities = capabilities
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -221,7 +227,7 @@ class OFPSwitchFeatures(MsgBase):
msg.n_tables,
msg.auxiliary_id,
msg.capabilities,
- msg.reserved) = struct.unpack_from(
+ msg._reserved) = struct.unpack_from(
ofproto_v1_3.OFP_SWITCH_FEATURES_PACK_STR, msg.buf,
ofproto_v1_3.OFP_HEADER_SIZE)
return msg
@@ -236,8 +242,10 @@ class OFPGetConfigRequest(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_GET_CONFIG_REPLY)
class OFPGetConfigReply(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, flags=None, miss_send_len=None):
super(OFPGetConfigReply, self).__init__(datapath)
+ self.flags = flags
+ self.miss_send_len = miss_send_len
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -340,12 +348,36 @@ class FlowWildcards(object):
return not self.wildcards & (1 << shift)
-class OFPMatch(object):
- def __init__(self):
+class OFPMatch(StringifyMixin):
+ def __init__(self, fields=[], type_=None):
super(OFPMatch, self).__init__()
self._wc = FlowWildcards()
self._flow = Flow()
self.fields = []
+ # accept type_ and length to be compatible with parser
+ if not type_ is None:
+ self.type = type_
+ if fields:
+ # we are doing de-stringify.
+ # we have two goals:
+ # - the resulted object should be serialize()-able.
+ # - the resulted object should be inspectable by applications.
+ # ie. fields[] should be filled.
+ # mimic appropriate set_foo calls and the first half of serialize.
+ import sys
+ this_module = sys.modules[__name__]
+ for o in fields:
+ assert len(o) == 1
+ for k, v in o.iteritems():
+ cls = getattr(this_module, k)
+ mask = v.get("mask", None)
+ header = OFPMatchField.cls_to_header(cls, not mask is None)
+ value = v["value"]
+ value = self._decode_value(value)
+ if not mask is None:
+ mask = self._decode_value(mask)
+ f = cls(header, value, mask)
+ self.fields.append(f)
def append_field(self, header, value, mask=None):
self.fields.append(OFPMatchField.make(header, value, mask))
@@ -584,7 +616,7 @@ class OFPMatch(object):
type_, length = struct.unpack_from('!HH', buf, offset)
match.type = type_
- match.length = length
+ match._length = length
# ofp_match adjustment
offset += 4
@@ -832,7 +864,7 @@ class OFPMatch(object):
self._flow.ipv6_exthdr = hdr
-class OFPMatchField(object):
+class OFPMatchField(StringifyMixin):
_FIELDS_HEADERS = {}
@staticmethod
@@ -845,13 +877,16 @@ class OFPMatchField(object):
def __init__(self, header):
self.header = header
- hasmask = (header >> 8) & 1
- if hasmask:
- self.n_bytes = (header & 0xff) / 2
- else:
- self.n_bytes = header & 0xff
+ self.n_bytes = ofproto_v1_3.oxm_tlv_header_extract_length(header)
self.length = 0
+ @classmethod
+ def cls_to_header(cls, cls_, hasmask):
+ # XXX efficiency
+ inv = dict((v, k) for k, v in cls._FIELDS_HEADERS.iteritems()
+ if (((k >> 8) & 1) != 0) == hasmask)
+ return inv[cls_]
+
@staticmethod
def make(header, value, mask=None):
cls_ = OFPMatchField._FIELDS_HEADERS.get(header)
@@ -872,7 +907,7 @@ class OFPMatchField(object):
def field_parser(cls, header, buf, offset):
hasmask = (header >> 8) & 1
mask = None
- if hasmask:
+ if ofproto_v1_3.oxm_tlv_header_extract_hasmask(header):
pack_str = '!' + cls.pack_str[1:] * 2
(value, mask) = struct.unpack_from(pack_str, buf, offset + 4)
else:
@@ -880,8 +915,7 @@ class OFPMatchField(object):
return cls(header, value, mask)
def serialize(self, buf, offset):
- hasmask = (self.header >> 8) & 1
- if hasmask:
+ if ofproto_v1_3.oxm_tlv_header_extract_hasmask(self.header):
self.put_w(buf, offset, self.value, self.mask)
else:
self.put(buf, offset, self.value)
@@ -917,6 +951,23 @@ class OFPMatchField(object):
def oxm_len(self):
return self.header & 0xff
+ def to_jsondict(self):
+ # remove some redundant attributes
+ d = super(OFPMatchField, self).to_jsondict()
+ v = d[self.__class__.__name__]
+ del v['header']
+ del v['length']
+ del v['n_bytes']
+ if 'mask' in v and v['mask'] is None:
+ del v['mask']
+ return d
+
+ @classmethod
+ def from_jsondict(cls, dict_):
+ # just pass the dict around.
+ # it will be converted by OFPMatch.__init__().
+ return {cls.__name__: dict_}
+
@OFPMatchField.register_field_header([ofproto_v1_3.OXM_OF_IN_PORT])
class MTInPort(OFPMatchField):
@@ -1182,11 +1233,10 @@ class MTArpTha(OFPMatchField):
self.mask = mask
-class MTIPv6(object):
+class MTIPv6(StringifyMixin):
@classmethod
def field_parser(cls, header, buf, offset):
- hasmask = (header >> 8) & 1
- if hasmask:
+ if ofproto_v1_3.oxm_tlv_header_extract_hasmask(header):
pack_str = '!' + cls.pack_str[1:] * 2
value = struct.unpack_from(pack_str, buf, offset + 4)
return cls(header, list(value[:8]), list(value[8:]))
@@ -1342,8 +1392,16 @@ class MTIPv6ExtHdr(OFPMatchField):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_PACKET_IN)
class OFPPacketIn(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, buffer_id=None, total_len=None, reason=None,
+ table_id=None, cookie=None, match=None, data=None):
super(OFPPacketIn, self).__init__(datapath)
+ self.buffer_id = buffer_id
+ self.total_len = total_len
+ self.reason = reason
+ self.table_id = table_id
+ self.cookie = cookie
+ self.match = match
+ self.data = data
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -1357,7 +1415,7 @@ class OFPPacketIn(MsgBase):
msg.match = OFPMatch.parser(msg.buf, ofproto_v1_3.OFP_PACKET_IN_SIZE -
ofproto_v1_3.OFP_MATCH_SIZE)
- match_len = utils.round_up(msg.match.length, 8)
+ match_len = utils.round_up(msg.match._length, 8)
msg.data = msg.buf[(ofproto_v1_3.OFP_PACKET_IN_SIZE -
ofproto_v1_3.OFP_MATCH_SIZE + match_len + 2):]
@@ -1371,8 +1429,22 @@ class OFPPacketIn(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_FLOW_REMOVED)
class OFPFlowRemoved(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, cookie=None, priority=None, reason=None,
+ table_id=None, duration_sec=None, duration_nsec=None,
+ idle_timeout=None, hard_timeout=None, packet_count=None,
+ byte_count=None, match=None):
super(OFPFlowRemoved, self).__init__(datapath)
+ self.cookie = cookie
+ self.priority = priority
+ self.reason = reason
+ self.table_id = table_id
+ self.duration_sec = duration_sec
+ self.duration_nsec = duration_nsec
+ self.idle_timeout = idle_timeout
+ self.hard_timeout = hard_timeout
+ self.packet_count = packet_count
+ self.byte_count = byte_count
+ self.match = match
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -1394,7 +1466,7 @@ class OFPFlowRemoved(MsgBase):
return msg
-class OFPPort(collections.namedtuple('OFPPort', (
+class OFPPort(ofproto_parser.namedtuple('OFPPort', (
'port_no', 'hw_addr', 'name', 'config', 'state', 'curr',
'advertised', 'supported', 'peer', 'curr_speed', 'max_speed'))):
@@ -1409,8 +1481,10 @@ class OFPPort(collections.namedtuple('OFPPort', (
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_PORT_STATUS)
class OFPPortStatus(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, reason=None, desc=None):
super(OFPPortStatus, self).__init__(datapath)
+ self.reason = reason
+ self.desc = desc
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -1433,17 +1507,17 @@ class OFPPacketOut(MsgBase):
super(OFPPacketOut, self).__init__(datapath)
self.buffer_id = buffer_id
self.in_port = in_port
- self.actions_len = 0
+ self._actions_len = 0
self.actions = actions
self.data = data
def _serialize_body(self):
- self.actions_len = 0
+ self._actions_len = 0
offset = ofproto_v1_3.OFP_PACKET_OUT_SIZE
for a in self.actions:
a.serialize(self.buf, offset)
offset += a.len
- self.actions_len += a.len
+ self._actions_len += a.len
if self.data is not None:
assert self.buffer_id == 0xffffffff
@@ -1451,7 +1525,7 @@ class OFPPacketOut(MsgBase):
msg_pack_into(ofproto_v1_3.OFP_PACKET_OUT_PACK_STR,
self.buf, ofproto_v1_3.OFP_HEADER_SIZE,
- self.buffer_id, self.in_port, self.actions_len)
+ self.buffer_id, self.in_port, self._actions_len)
@_set_msg_type(ofproto_v1_3.OFPT_FLOW_MOD)
@@ -1512,7 +1586,9 @@ class OFPInstruction(object):
@OFPInstruction.register_instruction_type([ofproto_v1_3.OFPIT_GOTO_TABLE])
-class OFPInstructionGotoTable(object):
+class OFPInstructionGotoTable(StringifyMixin):
+ _base_attributes = ['type', 'len']
+
def __init__(self, table_id):
super(OFPInstructionGotoTable, self).__init__()
self.type = ofproto_v1_3.OFPIT_GOTO_TABLE
@@ -1532,7 +1608,9 @@ class OFPInstructionGotoTable(object):
@OFPInstruction.register_instruction_type([ofproto_v1_3.OFPIT_WRITE_METADATA])
-class OFPInstructionWriteMetadata(object):
+class OFPInstructionWriteMetadata(StringifyMixin):
+ _base_attributes = ['type', 'len']
+
def __init__(self, metadata, metadata_mask):
super(OFPInstructionWriteMetadata, self).__init__()
self.type = ofproto_v1_3.OFPIT_WRITE_METADATA
@@ -1556,7 +1634,9 @@ class OFPInstructionWriteMetadata(object):
@OFPInstruction.register_instruction_type([ofproto_v1_3.OFPIT_WRITE_ACTIONS,
ofproto_v1_3.OFPIT_APPLY_ACTIONS,
ofproto_v1_3.OFPIT_CLEAR_ACTIONS])
-class OFPInstructionActions(object):
+class OFPInstructionActions(StringifyMixin):
+ _base_attributes = ['len']
+
def __init__(self, type_, actions=None):
super(OFPInstructionActions, self).__init__()
self.type = type_
@@ -1598,7 +1678,9 @@ class OFPInstructionActions(object):
@OFPInstruction.register_instruction_type([ofproto_v1_3.OFPIT_METER])
-class OFPInstructionMeter(object):
+class OFPInstructionMeter(StringifyMixin):
+ _base_attributes = ['type', 'len']
+
def __init__(self, meter_id):
super(OFPInstructionMeter, self).__init__()
self.type = ofproto_v1_3.OFPIT_METER
@@ -1617,7 +1699,9 @@ class OFPInstructionMeter(object):
buf, offset, self.type, self.len, self.meter_id)
-class OFPActionHeader(object):
+class OFPActionHeader(StringifyMixin):
+ _base_attributes = ['type', 'len']
+
def __init__(self, type_, len_):
self.type = type_
self.len = len_
@@ -1899,10 +1983,9 @@ class OFPActionExperimenter(OFPAction):
buf, offset, self.type, self.len, self.experimenter)
-class OFPBucket(object):
- def __init__(self, len_, weight, watch_port, watch_group, actions):
+class OFPBucket(StringifyMixin):
+ def __init__(self, weight, watch_port, watch_group, actions):
super(OFPBucket, self).__init__()
- self.len = len_
self.weight = weight
self.watch_port = watch_port
self.watch_group = watch_group
@@ -1912,11 +1995,12 @@ class OFPBucket(object):
def parser(cls, buf, offset):
(len_, weight, watch_port, watch_group) = struct.unpack_from(
ofproto_v1_3.OFP_BUCKET_PACK_STR, buf, offset)
- msg = cls(len_, weight, watch_port, watch_group, [])
+ msg = cls(weight, watch_port, watch_group, [])
+ msg._len = len_
length = ofproto_v1_3.OFP_BUCKET_SIZE
offset += ofproto_v1_3.OFP_BUCKET_SIZE
- while length < msg.len:
+ while length < msg._len:
action = OFPAction.parser(buf, offset)
msg.actions.append(action)
offset += action.len
@@ -1932,10 +2016,11 @@ class OFPBucket(object):
action_offset += a.len
action_len += a.len
- self.len = utils.round_up(ofproto_v1_3.OFP_BUCKET_SIZE + action_len,
- 8)
+ self._len = utils.round_up(ofproto_v1_3.OFP_BUCKET_SIZE + action_len,
+ 8)
msg_pack_into(ofproto_v1_3.OFP_BUCKET_PACK_STR, buf, offset,
- self.len, self.weight, self.watch_port, self.watch_group)
+ self._len, self.weight, self.watch_port,
+ self.watch_group)
@_set_msg_type(ofproto_v1_3.OFPT_GROUP_MOD)
@@ -1955,7 +2040,7 @@ class OFPGroupMod(MsgBase):
offset = ofproto_v1_3.OFP_GROUP_MOD_SIZE
for b in self.buckets:
b.serialize(self.buf, offset)
- offset += b.len
+ offset += b._len
@_set_msg_type(ofproto_v1_3.OFPT_PORT_MOD)
@@ -2002,7 +2087,7 @@ class OFPMultipartRequest(MsgBase):
assert flags == 0 # none yet defined
super(OFPMultipartRequest, self).__init__(datapath)
- self.type = self.__class__.cls_stats_type
+ self._type = self.__class__.cls_stats_type
self.flags = flags
def _serialize_stats_body(self):
@@ -2011,7 +2096,7 @@ class OFPMultipartRequest(MsgBase):
def _serialize_body(self):
msg_pack_into(ofproto_v1_3.OFP_MULTIPART_REQUEST_PACK_STR,
self.buf, ofproto_v1_3.OFP_HEADER_SIZE,
- self.type, self.flags)
+ self._type, self.flags)
self._serialize_stats_body()
@@ -2031,8 +2116,10 @@ class OFPMultipartReply(MsgBase):
return cls
return _register_stats_type
- def __init__(self, datapath):
+ def __init__(self, datapath, body=None, flags=None):
super(OFPMultipartReply, self).__init__(datapath)
+ self.body = body
+ self.flags = flags
@classmethod
def parser_stats_body(cls, buf, msg_len, offset):
@@ -2071,7 +2158,7 @@ class OFPMultipartReply(MsgBase):
while offset < msg_len:
b = stats_type_cls.cls_stats_body_cls.parser(msg.buf, offset)
body.append(b)
- offset += b.length
+ offset += b._length
if stats_type_cls.cls_body_single_struct:
msg.body = body[0]
@@ -2080,14 +2167,14 @@ class OFPMultipartReply(MsgBase):
return msg
-class OFPDescStats(collections.namedtuple('OFPDescStats', (
+class OFPDescStats(ofproto_parser.namedtuple('OFPDescStats', (
'mfr_desc', 'hw_desc', 'sw_desc', 'serial_num', 'dp_desc'))):
@classmethod
def parser(cls, buf, offset):
desc = struct.unpack_from(ofproto_v1_3.OFP_DESC_PACK_STR,
buf, offset)
stats = cls(*desc)
- stats.length = ofproto_v1_3.OFP_DESC_SIZE
+ stats._length = ofproto_v1_3.OFP_DESC_SIZE
return stats
@@ -2102,31 +2189,35 @@ class OFPDescStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_DESC, OFPDescStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPDescStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPDescStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPDescStatsReply, self).__init__(datapath, **kwargs)
-class OFPFlowStats(object):
- def __init__(self):
+class OFPFlowStats(StringifyMixin):
+ def __init__(self, table_id=None, duration_sec=None, duration_nsec=None,
+ priority=None, idle_timeout=None, hard_timeout=None,
+ flags=None, cookie=None, packet_count=None,
+ byte_count=None, match=None, instructions=None):
super(OFPFlowStats, self).__init__()
- self.length = None
- self.table_id = None
- self.duration_sec = None
- self.duration_nsec = None
- self.priority = None
- self.idle_timeout = None
- self.hard_timeout = None
- self.flags = None
- self.cookie = None
- self.packet_count = None
- self.byte_count = None
- self.match = None
+ self._length = 0
+ self.table_id = table_id
+ self.duration_sec = duration_sec
+ self.duration_nsec = duration_nsec
+ self.priority = priority
+ self.idle_timeout = idle_timeout
+ self.hard_timeout = hard_timeout
+ self.flags = flags
+ self.cookie = cookie
+ self.packet_count = packet_count
+ self.byte_count = byte_count
+ self.match = match
+ self.instructions = instructions
@classmethod
def parser(cls, buf, offset):
flow_stats = cls()
- (flow_stats.length, flow_stats.table_id,
+ (flow_stats._length, flow_stats.table_id,
flow_stats.duration_sec, flow_stats.duration_nsec,
flow_stats.priority, flow_stats.idle_timeout,
flow_stats.hard_timeout, flow_stats.flags,
@@ -2136,10 +2227,10 @@ class OFPFlowStats(object):
offset += ofproto_v1_3.OFP_FLOW_STATS_0_SIZE
flow_stats.match = OFPMatch.parser(buf, offset)
- match_length = utils.round_up(flow_stats.match.length, 8)
- inst_length = (flow_stats.length - (ofproto_v1_3.OFP_FLOW_STATS_SIZE -
- ofproto_v1_3.OFP_MATCH_SIZE +
- match_length))
+ match_length = utils.round_up(flow_stats.match._length, 8)
+ inst_length = (flow_stats._length - (ofproto_v1_3.OFP_FLOW_STATS_SIZE -
+ ofproto_v1_3.OFP_MATCH_SIZE +
+ match_length))
offset += match_length
instructions = []
while inst_length > 0:
@@ -2187,18 +2278,18 @@ class OFPFlowStatsRequest(OFPFlowStatsRequestBase):
@_set_stats_type(ofproto_v1_3.OFPMP_FLOW, OFPFlowStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPFlowStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPFlowStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPFlowStatsReply, self).__init__(datapath, **kwargs)
-class OFPAggregateStats(collections.namedtuple('OFPAggregateStats', (
+class OFPAggregateStats(ofproto_parser.namedtuple('OFPAggregateStats', (
'packet_count', 'byte_count', 'flow_count'))):
@classmethod
def parser(cls, buf, offset):
agg = struct.unpack_from(
ofproto_v1_3.OFP_AGGREGATE_STATS_REPLY_PACK_STR, buf, offset)
stats = cls(*agg)
- stats.length = ofproto_v1_3.OFP_AGGREGATE_STATS_REPLY_SIZE
+ stats._length = ofproto_v1_3.OFP_AGGREGATE_STATS_REPLY_SIZE
return stats
@@ -2217,15 +2308,15 @@ class OFPAggregateStatsRequest(OFPFlowStatsRequestBase):
match)
-@OFPMultipartReply.register_stats_type()
+@OFPMultipartReply.register_stats_type(body_single_struct=True)
@_set_stats_type(ofproto_v1_3.OFPMP_AGGREGATE, OFPAggregateStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPAggregateStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPAggregateStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPAggregateStatsReply, self).__init__(datapath, **kwargs)
-class OFPTableStats(collections.namedtuple('OFPTableStats', (
+class OFPTableStats(ofproto_parser.namedtuple('OFPTableStats', (
'table_id', 'active_count', 'lookup_count',
'matched_count'))):
@classmethod
@@ -2233,7 +2324,7 @@ class OFPTableStats(collections.namedtuple('OFPTableStats', (
tbl = struct.unpack_from(ofproto_v1_3.OFP_TABLE_STATS_PACK_STR,
buf, offset)
stats = cls(*tbl)
- stats.length = ofproto_v1_3.OFP_TABLE_STATS_SIZE
+ stats._length = ofproto_v1_3.OFP_TABLE_STATS_SIZE
return stats
@@ -2248,11 +2339,11 @@ class OFPTableStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_TABLE, OFPTableStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPTableStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPTableStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPTableStatsReply, self).__init__(datapath, **kwargs)
-class OFPPortStats(collections.namedtuple('OFPPortStats', (
+class OFPPortStats(ofproto_parser.namedtuple('OFPPortStats', (
'port_no', 'rx_packets', 'tx_packets', 'rx_bytes', 'tx_bytes',
'rx_dropped', 'tx_dropped', 'rx_errors', 'tx_errors',
'rx_frame_err', 'rx_over_err', 'rx_crc_err', 'collisions',
@@ -2262,7 +2353,7 @@ class OFPPortStats(collections.namedtuple('OFPPortStats', (
port = struct.unpack_from(ofproto_v1_3.OFP_PORT_STATS_PACK_STR,
buf, offset)
stats = cls(*port)
- stats.length = ofproto_v1_3.OFP_PORT_STATS_SIZE
+ stats._length = ofproto_v1_3.OFP_PORT_STATS_SIZE
return stats
@@ -2284,11 +2375,11 @@ class OFPPortStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_PORT_STATS, OFPPortStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPPortStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPPortStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPPortStatsReply, self).__init__(datapath, **kwargs)
-class OFPQueueStats(collections.namedtuple('OFPQueueStats', (
+class OFPQueueStats(ofproto_parser.namedtuple('OFPQueueStats', (
'port_no', 'queue_id', 'tx_bytes', 'tx_packets', 'tx_errors',
'duration_sec', 'duration_nsec'))):
@classmethod
@@ -2296,7 +2387,7 @@ class OFPQueueStats(collections.namedtuple('OFPQueueStats', (
queue = struct.unpack_from(ofproto_v1_3.OFP_QUEUE_STATS_PACK_STR,
buf, offset)
stats = cls(*queue)
- stats.length = ofproto_v1_3.OFP_QUEUE_STATS_SIZE
+ stats._length = ofproto_v1_3.OFP_QUEUE_STATS_SIZE
return stats
@@ -2319,11 +2410,11 @@ class OFPQueueStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_QUEUE, OFPQueueStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPQueueStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPQueueStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPQueueStatsReply, self).__init__(datapath, **kwargs)
-class OFPGroupStats(collections.namedtuple('OFPGroupStats', (
+class OFPGroupStats(ofproto_parser.namedtuple('OFPGroupStats', (
'length', 'group_id', 'ref_count', 'packet_count',
'byte_count', 'duration_sec', 'duration_nsec'))):
@classmethod
@@ -2331,7 +2422,7 @@ class OFPGroupStats(collections.namedtuple('OFPGroupStats', (
group = struct.unpack_from(ofproto_v1_3.OFP_GROUP_STATS_PACK_STR,
buf, offset)
stats = cls(*group)
- stats.length = ofproto_v1_3.OFP_GROUP_STATS_SIZE
+ stats._length = ofproto_v1_3.OFP_GROUP_STATS_SIZE
return stats
@@ -2357,30 +2448,29 @@ class OFPGroupStatsReply(OFPMultipartReply):
super(OFPGroupStatsReply, self).__init__(datapath)
-class OFPGroupDescStats(object):
- def __init__(self):
+class OFPGroupDescStats(StringifyMixin):
+ def __init__(self, type_=None, group_id=None, buckets=None):
super(OFPGroupDescStats, self).__init__()
- self.length = None
- self.type = None
- self.group_id = None
- self.buckets = None
+ self.type = type_
+ self.group_id = group_id
+ self.buckets = buckets
@classmethod
def parser(cls, buf, offset):
stats = cls()
- (stats.length, stats.type, stats.group_id) = struct.unpack_from(
+ (stats._length, stats.type, stats.group_id) = struct.unpack_from(
ofproto_v1_3.OFP_GROUP_DESC_STATS_PACK_STR, buf, offset)
offset += ofproto_v1_3.OFP_GROUP_DESC_STATS_SIZE
stats.buckets = []
length = ofproto_v1_3.OFP_GROUP_DESC_STATS_SIZE
- while length < stats.length:
+ while length < stats._length:
bucket = OFPBucket.parser(buf, offset)
stats.buckets.append(bucket)
- offset += bucket.len
- length += bucket.len
+ offset += bucket._len
+ length += bucket._len
return stats
@@ -2396,12 +2486,13 @@ class OFPGroupDescStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_GROUP_DESC, OFPGroupDescStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPGroupDescStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPGroupDescStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPGroupDescStatsReply, self).__init__(datapath, **kwargs)
-class OFPGroupFeaturesStats(collections.namedtuple('OFPGroupFeaturesStats', (
- 'types', 'capabilities', 'max_groups', 'actions'))):
+class OFPGroupFeaturesStats(ofproto_parser.namedtuple('OFPGroupFeaturesStats',
+ ('types', 'capabilities', 'max_groups',
+ 'actions'))):
@classmethod
def parser(cls, buf, offset):
group_features = struct.unpack_from(
@@ -2411,7 +2502,7 @@ class OFPGroupFeaturesStats(collections.namedtuple('OFPGroupFeaturesStats', (
max_groups = list(group_features[2:6])
actions = list(group_features[6:10])
stats = cls(types, capabilities, max_groups, actions)
- stats.length = ofproto_v1_3.OFP_GROUP_FEATURES_SIZE
+ stats._length = ofproto_v1_3.OFP_GROUP_FEATURES_SIZE
return stats
@@ -2422,15 +2513,15 @@ class OFPGroupFeaturesStatsRequest(OFPMultipartRequest):
super(OFPGroupFeaturesStatsRequest, self).__init__(datapath, flags)
-@OFPMultipartReply.register_stats_type()
+@OFPMultipartReply.register_stats_type(body_single_struct=True)
@_set_stats_type(ofproto_v1_3.OFPMP_GROUP_FEATURES, OFPGroupFeaturesStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPGroupFeaturesStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPGroupFeaturesStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPGroupFeaturesStatsReply, self).__init__(datapath, **kwargs)
-class OFPMeterBandStats(object):
+class OFPMeterBandStats(StringifyMixin):
def __init__(self, packet_band_count, byte_band_count):
super(OFPMeterBandStats, self).__init__()
self.packet_band_count = packet_band_count
@@ -2443,23 +2534,24 @@ class OFPMeterBandStats(object):
return cls(*band_stats)
-class OFPMeterStats(object):
- def __init__(self):
+class OFPMeterStats(StringifyMixin):
+ def __init__(self, meter_id=None, flow_count=None, packet_in_count=None,
+ byte_in_count=None, duration_sec=None, duration_nsec=None,
+ band_stats=None):
super(OFPMeterStats, self).__init__()
- self.meter_id = None
- self.length = None
- self.flow_count = None
- self.packet_in_count = None
- self.byte_in_count = None
- self.duration_sec = None
- self.duration_nsec = None
- self.band_stats = None
+ self.meter_id = meter_id
+ self.flow_count = flow_count
+ self.packet_in_count = packet_in_count
+ self.byte_in_count = byte_in_count
+ self.duration_sec = duration_sec
+ self.duration_nsec = duration_nsec
+ self.band_stats = band_stats
@classmethod
def parser(cls, buf, offset):
meter_stats = cls()
- (meter_stats.meter_id, meter_stats.length,
+ (meter_stats.meter_id, meter_stats._length,
meter_stats.flow_count, meter_stats.packet_in_count,
meter_stats.byte_in_count, meter_stats.duration_sec,
meter_stats.duration_nsec) = struct.unpack_from(
@@ -2468,7 +2560,7 @@ class OFPMeterStats(object):
meter_stats.band_stats = []
length = ofproto_v1_3.OFP_METER_STATS_SIZE
- while length < meter_stats.length:
+ while length < meter_stats._length:
band_stats = OFPMeterBandStats.parser(buf, offset)
meter_stats.band_stats.append(band_stats)
offset += ofproto_v1_3.OFP_METER_BAND_STATS_SIZE
@@ -2495,11 +2587,11 @@ class OFPMeterStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_METER, OFPMeterStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPMeterStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPMeterStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPMeterStatsReply, self).__init__(datapath, **kwargs)
-class OFPMeterBandHeader(object):
+class OFPMeterBandHeader(StringifyMixin):
def __init__(self, type_, len_, rate, burst_size):
self.type = type_
self.len = len_
@@ -2513,26 +2605,26 @@ class OFPMeterBandHeader(object):
return cls(*band_header)
-class OFPMeterConfigStats(object):
- def __init__(self):
+class OFPMeterConfigStats(StringifyMixin):
+ def __init__(self, flags=None, meter_id=None, bands=None):
super(OFPMeterConfigStats, self).__init__()
- self.length = None
- self.flags = None
- self.meter_id = None
- self.bands = None
+ self._length = None
+ self.flags = flags
+ self.meter_id = meter_id
+ self.bands = bands
@classmethod
def parser(cls, buf, offset):
meter_config = cls()
- (meter_config.length, meter_config.flags,
+ (meter_config._length, meter_config.flags,
meter_config.meter_id) = struct.unpack_from(
ofproto_v1_3.OFP_METER_CONFIG_PACK_STR, buf, offset)
offset += ofproto_v1_3.OFP_METER_CONFIG_SIZE
meter_config.bands = []
length = ofproto_v1_3.OFP_METER_CONFIG_SIZE
- while length < meter_config.length:
+ while length < meter_config._length:
band_header = OFPMeterBandHeader.parser(buf, offset)
meter_config.bands.append(band_header)
offset += band_header.len
@@ -2559,19 +2651,19 @@ class OFPMeterConfigStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_METER_CONFIG, OFPMeterConfigStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPMeterConfigStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPMeterConfigStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPMeterConfigStatsReply, self).__init__(datapath, **kwargs)
-class OFPMeterFeaturesStats(collections.namedtuple('OFPMeterFeaturesStats', (
- 'max_meter', 'band_types', 'capabilities', 'max_band',
- 'max_color'))):
+class OFPMeterFeaturesStats(ofproto_parser.namedtuple('OFPMeterFeaturesStats',
+ ('max_meter', 'band_types', 'capabilities',
+ 'max_band', 'max_color'))):
@classmethod
def parser(cls, buf, offset):
meter_features = struct.unpack_from(
ofproto_v1_3.OFP_METER_FEATURES_PACK_STR, buf, offset)
stats = cls(*meter_features)
- stats.length = ofproto_v1_3.OFP_METER_FEATURES_SIZE
+ stats._length = ofproto_v1_3.OFP_METER_FEATURES_SIZE
return stats
@@ -2586,11 +2678,11 @@ class OFPMeterFeaturesStatsRequest(OFPMultipartRequest):
@_set_stats_type(ofproto_v1_3.OFPMP_METER_FEATURES, OFPMeterFeaturesStats)
@_set_msg_type(ofproto_v1_3.OFPT_MULTIPART_REPLY)
class OFPMeterFeaturesStatsReply(OFPMultipartReply):
- def __init__(self, datapath):
- super(OFPMeterFeaturesStatsReply, self).__init__(datapath)
+ def __init__(self, datapath, **kwargs):
+ super(OFPMeterFeaturesStatsReply, self).__init__(datapath, **kwargs)
-class OFPTableFeaturesStats(object):
+class OFPTableFeaturesStats(StringifyMixin):
def __init__(self):
super(OFPTableFeaturesStats, self).__init__()
self.length = None
@@ -2688,14 +2780,14 @@ class OFPQueueGetConfigRequest(MsgBase):
self.buf, ofproto_v1_3.OFP_HEADER_SIZE, self.port)
-class OFPQueuePropHeader(object):
+class OFPQueuePropHeader(StringifyMixin):
def __init__(self, property_, len_):
- self.property = property_
- self.len = len_
+ self._property = property_
+ self._len = len_
def serialize(self, buf, offset):
msg_pack_into(ofproto_v1_3.OFP_QUEUE_PROP_HEADER_PACK_STR,
- buf, offset, self.property, self.len)
+ buf, offset, self._property, self._len)
class OFPQueueProp(OFPQueuePropHeader):
@@ -2758,12 +2850,11 @@ class OFPQueuePropMaxRate(OFPQueueProp):
# TODO: add ofp_queue_prop_experimenter
-class OFPPacketQueue(object):
- def __init__(self, queue_id, port, len_, properties):
+class OFPPacketQueue(StringifyMixin):
+ def __init__(self, queue_id, port, properties):
super(OFPPacketQueue, self).__init__()
self.queue_id = queue_id
self.port = port
- self.len = len_
self.properties = properties
@classmethod
@@ -2776,16 +2867,20 @@ class OFPPacketQueue(object):
while length < len_:
queue_prop = OFPQueueProp.parser(buf, offset)
properties.append(queue_prop)
- offset += queue_prop.len
- length += queue_prop.len
- return cls(queue_id, port, len_, properties)
+ offset += queue_prop._len
+ length += queue_prop._len
+ o = cls(queue_id, port, properties)
+ o._len = len_
+ return o
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_QUEUE_GET_CONFIG_REPLY)
class OFPQueueGetConfigReply(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, queues=None, port=None):
super(OFPQueueGetConfigReply, self).__init__(datapath)
+ self.queues = queues
+ self.port = port
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -2801,7 +2896,7 @@ class OFPQueueGetConfigReply(MsgBase):
while offset < msg_len:
queue = OFPPacketQueue.parser(msg.buf, offset)
msg.queues.append(queue)
- offset += queue.len
+ offset += queue._len
return msg
@@ -2824,10 +2919,10 @@ class OFPRoleRequest(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_ROLE_REPLY)
class OFPRoleReply(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, role=None, generation_id=None):
super(OFPRoleReply, self).__init__(datapath)
- self.role = None
- self.generation_id = None
+ self.role = role
+ self.generation_id = generation_id
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -2849,11 +2944,12 @@ class OFPGetAsyncRequest(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_3.OFPT_GET_ASYNC_REPLY)
class OFPGetAsyncReply(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, packet_in_mask=None, port_status_mask=None,
+ flow_removed_mask=None):
super(OFPGetAsyncReply, self).__init__(datapath)
- self.packet_in_mask = None
- self.port_status_mask = None
- self.flow_removed_mask = None
+ self.packet_in_mask = packet_in_mask
+ self.port_status_mask = port_status_mask
+ self.flow_removed_mask = flow_removed_mask
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):