Signed-off-by: YAMAMOTO Takashi <[email protected]>
---
ryu/ofproto/ofproto_v1_2.py | 12 ++
ryu/ofproto/ofproto_v1_2_parser.py | 246 +++++++++++++++++++++++++------------
2 files changed, 180 insertions(+), 78 deletions(-)
diff --git a/ryu/ofproto/ofproto_v1_2.py b/ryu/ofproto/ofproto_v1_2.py
index 27fc6b3..e2bda20 100644
--- a/ryu/ofproto/ofproto_v1_2.py
+++ b/ryu/ofproto/ofproto_v1_2.py
@@ -805,6 +805,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_2_parser.py
b/ryu/ofproto/ofproto_v1_2_parser.py
index 112cd45..d13d044 100644
--- a/ryu/ofproto/ofproto_v1_2_parser.py
+++ b/ryu/ofproto/ofproto_v1_2_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_2
@@ -165,7 +164,7 @@ class OFPExperimenter(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'))):
@@ -184,8 +183,14 @@ class OFPFeaturesRequest(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_2.OFPT_FEATURES_REPLY)
class OFPSwitchFeatures(MsgBase):
- def __init__(self, datapath):
+ def __init__(self, datapath, datapath_id=None, n_buffers=None,
+ n_tables=None, capabilities=None, ports=None):
super(OFPSwitchFeatures, self).__init__(datapath)
+ self.datapath_id = datapath_id
+ self.n_buffers = n_buffers
+ self.n_tables = n_tables
+ self.capabilities = capabilities
+ self.ports = ports
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -195,7 +200,7 @@ class OFPSwitchFeatures(MsgBase):
msg.n_buffers,
msg.n_tables,
msg.capabilities,
- msg.reserved) = struct.unpack_from(
+ msg._reserved) = struct.unpack_from(
ofproto_v1_2.OFP_SWITCH_FEATURES_PACK_STR, msg.buf,
ofproto_v1_2.OFP_HEADER_SIZE)
@@ -251,8 +256,15 @@ class OFPSetConfig(MsgBase):
@_register_parser
@_set_msg_type(ofproto_v1_2.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, 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.match = match
+ self.data = data
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -334,17 +346,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_2.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
@@ -352,7 +364,7 @@ class OFPPacketOut(MsgBase):
msg_pack_into(ofproto_v1_2.OFP_PACKET_OUT_PACK_STR,
self.buf, ofproto_v1_2.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_2.OFPT_FLOW_MOD)
@@ -394,7 +406,7 @@ class OFPFlowMod(MsgBase):
offset += inst.len
-class OFPInstruction(object):
+class OFPInstruction(StringifyMixin):
_INSTRUCTION_TYPES = {}
@staticmethod
@@ -413,7 +425,9 @@ class OFPInstruction(object):
@OFPInstruction.register_instruction_type([ofproto_v1_2.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_2.OFPIT_GOTO_TABLE
@@ -433,7 +447,9 @@ class OFPInstructionGotoTable(object):
@OFPInstruction.register_instruction_type([ofproto_v1_2.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_2.OFPIT_WRITE_METADATA
@@ -457,7 +473,9 @@ class OFPInstructionWriteMetadata(object):
@OFPInstruction.register_instruction_type([ofproto_v1_2.OFPIT_WRITE_ACTIONS,
ofproto_v1_2.OFPIT_APPLY_ACTIONS,
ofproto_v1_2.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_
@@ -486,6 +504,7 @@ class OFPInstructionActions(object):
action_offset = offset + ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_SIZE
if self.actions:
for a in self.actions:
+ assert isinstance(a, OFPAction)
a.serialize(buf, action_offset)
action_offset += a.len
@@ -498,7 +517,9 @@ class OFPInstructionActions(object):
buf, offset, self.type, self.len)
-class OFPActionHeader(object):
+class OFPActionHeader(StringifyMixin):
+ _base_attributes = ['type', 'len']
+
def __init__(self, type_, len_):
self.type = type_
self.len = len_
@@ -795,7 +816,7 @@ class OFPActionExperimenter(OFPAction):
buf, offset, self.type, self.len, self.experimenter)
-class OFPBucket(object):
+class OFPBucket(StringifyMixin):
def __init__(self, len_, weight, watch_port, watch_group, actions):
super(OFPBucket, self).__init__()
self.len = len_
@@ -885,10 +906,17 @@ class OFPTableMod(MsgBase):
class OFPStatsRequest(MsgBase):
- def __init__(self, datapath, type_):
+ def __init__(self, datapath, type_, flags):
super(OFPStatsRequest, self).__init__(datapath)
self.type = type_
- self.flags = 0
+ self.flags = flags
+
+ def to_jsondict(self):
+ # remove some redundant attributes
+ d = super(OFPStatsRequest, self).to_jsondict()
+ v = d[self.__class__.__name__]
+ del v['type'] # implied by subclass
+ return d
def _serialize_stats_body(self):
pass
@@ -914,8 +942,18 @@ class OFPStatsReply(MsgBase):
return cls
return _register_stats_reply_type
- def __init__(self, datapath):
+ def __init__(self, datapath, type_=None, flags=None, body=None):
super(OFPStatsReply, self).__init__(datapath)
+ self.type = type_
+ self.flags = flags
+ self.body = body
+
+ def to_jsondict(self):
+ # remove some redundant attributes
+ d = super(OFPStatsReply, self).to_jsondict()
+ v = d[self.__class__.__name__]
+ del v['type'] # implied by subclass
+ return d
@classmethod
def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
@@ -943,14 +981,15 @@ class OFPStatsReply(MsgBase):
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPDescStatsRequest(OFPStatsRequest):
- def __init__(self, datapath):
+ def __init__(self, datapath, flags=0):
super(OFPDescStatsRequest, self).__init__(datapath,
- ofproto_v1_2.OFPST_DESC)
+ ofproto_v1_2.OFPST_DESC,
+ flags)
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_DESC,
body_single_struct=True)
-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):
@@ -964,9 +1003,10 @@ class OFPDescStats(collections.namedtuple('OFPDescStats',
(
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPFlowStatsRequest(OFPStatsRequest):
def __init__(self, datapath, table_id, out_port, out_group,
- cookie, cookie_mask, match):
+ cookie, cookie_mask, match, flags=0):
super(OFPFlowStatsRequest, self).__init__(datapath,
- ofproto_v1_2.OFPST_FLOW)
+ ofproto_v1_2.OFPST_FLOW,
+ flags)
self.table_id = table_id
self.out_port = out_port
self.out_group = out_group
@@ -988,7 +1028,7 @@ class OFPFlowStatsRequest(OFPStatsRequest):
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_FLOW)
-class OFPFlowStats(object):
+class OFPFlowStats(StringifyMixin):
def __init__(self, length, table_id, duration_sec, duration_nsec,
priority, idle_timeout, hard_timeout, cookie, packet_count,
byte_count, match, instructions=None):
@@ -1037,10 +1077,11 @@ class OFPFlowStats(object):
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPAggregateStatsRequest(OFPStatsRequest):
def __init__(self, datapath, table_id, out_port, out_group,
- cookie, cookie_mask, match):
+ cookie, cookie_mask, match, flags=0):
super(OFPAggregateStatsRequest, self).__init__(
datapath,
- ofproto_v1_2.OFPST_AGGREGATE)
+ ofproto_v1_2.OFPST_AGGREGATE,
+ flags)
self.table_id = table_id
self.out_port = out_port
self.out_group = out_group
@@ -1064,7 +1105,7 @@ class OFPAggregateStatsRequest(OFPStatsRequest):
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_AGGREGATE,
body_single_struct=True)
-class OFPAggregateStatsReply(collections.namedtuple('OFPAggregateStats', (
+class OFPAggregateStatsReply(ofproto_parser.namedtuple('OFPAggregateStats', (
'packet_count', 'byte_count', 'flow_count'))):
@classmethod
def parser(cls, buf, offset):
@@ -1078,21 +1119,22 @@ class
OFPAggregateStatsReply(collections.namedtuple('OFPAggregateStats', (
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPTableStatsRequest(OFPStatsRequest):
- def __init__(self, datapath):
+ def __init__(self, datapath, flags=0):
super(OFPTableStatsRequest, self).__init__(datapath,
- ofproto_v1_2.OFPST_TABLE)
+ ofproto_v1_2.OFPST_TABLE,
+ flags)
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_TABLE)
class OFPTableStats(
- collections.namedtuple('OFPTableStats',
- ('table_id', 'name', 'match', 'wildcards',
- 'write_actions', 'apply_actions',
- 'write_setfields', 'apply_setfields',
- 'metadata_match', 'metadata_write',
- 'instructions', 'config',
- 'max_entries', 'active_count',
- 'lookup_count', 'matched_count'))):
+ ofproto_parser.namedtuple('OFPTableStats',
+ ('table_id', 'name', 'match', 'wildcards',
+ 'write_actions', 'apply_actions',
+ 'write_setfields', 'apply_setfields',
+ 'metadata_match', 'metadata_write',
+ 'instructions', 'config',
+ 'max_entries', 'active_count',
+ 'lookup_count', 'matched_count'))):
@classmethod
def parser(cls, buf, offset):
table = struct.unpack_from(
@@ -1105,9 +1147,10 @@ class OFPTableStats(
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPPortStatsRequest(OFPStatsRequest):
- def __init__(self, datapath, port_no):
+ def __init__(self, datapath, port_no, flags=0):
super(OFPPortStatsRequest, self).__init__(datapath,
- ofproto_v1_2.OFPST_PORT)
+ ofproto_v1_2.OFPST_PORT,
+ flags)
self.port_no = port_no
def _serialize_stats_body(self):
@@ -1118,13 +1161,13 @@ class OFPPortStatsRequest(OFPStatsRequest):
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_PORT)
class OFPPortStats(
- collections.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'))):
+ 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'))):
@classmethod
def parser(cls, buf, offset):
port = struct.unpack_from(ofproto_v1_2.OFP_PORT_STATS_PACK_STR,
@@ -1136,9 +1179,10 @@ class OFPPortStats(
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPQueueStatsRequest(OFPStatsRequest):
- def __init__(self, datapath, port_no, queue_id):
+ def __init__(self, datapath, port_no, queue_id, flags=0):
super(OFPQueueStatsRequest, self).__init__(datapath,
- ofproto_v1_2.OFPST_QUEUE)
+ ofproto_v1_2.OFPST_QUEUE,
+ flags)
self.port_no = port_no
self.queue_id = queue_id
@@ -1150,9 +1194,9 @@ class OFPQueueStatsRequest(OFPStatsRequest):
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_QUEUE)
class OFPQueueStats(
- collections.namedtuple('OFPQueueStats',
- ('port_no', 'queue_id', 'tx_bytes',
- 'tx_packets', 'tx_errors'))):
+ ofproto_parser.namedtuple('OFPQueueStats',
+ ('port_no', 'queue_id', 'tx_bytes',
+ 'tx_packets', 'tx_errors'))):
@classmethod
def parser(cls, buf, offset):
queue = struct.unpack_from(ofproto_v1_2.OFP_QUEUE_STATS_PACK_STR,
@@ -1162,7 +1206,7 @@ class OFPQueueStats(
return stats
-class OFPBucketCounter(object):
+class OFPBucketCounter(StringifyMixin):
def __init__(self, packet_count, byte_count):
super(OFPBucketCounter, self).__init__()
self.packet_count = packet_count
@@ -1178,9 +1222,10 @@ class OFPBucketCounter(object):
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPGroupStatsRequest(OFPStatsRequest):
- def __init__(self, datapath, group_id):
+ def __init__(self, datapath, group_id, flags=0):
super(OFPGroupStatsRequest, self).__init__(datapath,
- ofproto_v1_2.OFPST_GROUP)
+ ofproto_v1_2.OFPST_GROUP,
+ flags)
self.group_id = group_id
def _serialize_stats_body(self):
@@ -1190,7 +1235,7 @@ class OFPGroupStatsRequest(OFPStatsRequest):
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_GROUP)
-class OFPGroupStats(object):
+class OFPGroupStats(StringifyMixin):
def __init__(self, length, group_id, ref_count, packet_count,
byte_count, bucket_counters):
super(OFPGroupStats, self).__init__()
@@ -1222,14 +1267,15 @@ class OFPGroupStats(object):
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPGroupDescStatsRequest(OFPStatsRequest):
- def __init__(self, datapath):
+ def __init__(self, datapath, flags=0):
super(OFPGroupDescStatsRequest, self).__init__(
datapath,
- ofproto_v1_2.OFPST_GROUP_DESC)
+ ofproto_v1_2.OFPST_GROUP_DESC,
+ flags)
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_GROUP_DESC)
-class OFPGroupDescStats(object):
+class OFPGroupDescStats(StringifyMixin):
def __init__(self, length, type_, group_id, buckets):
self.length = length
self.type = type_
@@ -1256,15 +1302,16 @@ class OFPGroupDescStats(object):
@_set_msg_type(ofproto_v1_2.OFPT_STATS_REQUEST)
class OFPGroupFeaturesStatsRequest(OFPStatsRequest):
- def __init__(self, datapath):
+ def __init__(self, datapath, flags=0):
super(OFPGroupFeaturesStatsRequest, self).__init__(
datapath,
- ofproto_v1_2.OFPST_GROUP_FEATURES)
+ ofproto_v1_2.OFPST_GROUP_FEATURES,
+ flags)
@OFPStatsReply.register_stats_reply_type(ofproto_v1_2.OFPST_GROUP_FEATURES,
body_single_struct=True)
-class OFPGroupFeaturesStats(object):
+class OFPGroupFeaturesStats(StringifyMixin):
def __init__(self, types, capabilities, max_groups, actions):
self.types = types
self.capabilities = capabilities
@@ -1294,7 +1341,7 @@ class OFPQueueGetConfigRequest(MsgBase):
self.buf, ofproto_v1_2.OFP_HEADER_SIZE, self.port)
-class OFPQueuePropHeader(object):
+class OFPQueuePropHeader(StringifyMixin):
def __init__(self, property_, len_):
self.property = property_
self.len = len_
@@ -1331,7 +1378,7 @@ class OFPQueueProp(OFPQueuePropHeader):
return cls_.parser(buf, offset)
-class OFPPacketQueue(object):
+class OFPPacketQueue(StringifyMixin):
def __init__(self, queue_id, port, len_, properties):
super(OFPPacketQueue, self).__init__()
self.queue_id = queue_id
@@ -1518,12 +1565,38 @@ class FlowWildcards(object):
return not self.wildcards & (1 << shift)
-class OFPMatch(object):
- def __init__(self):
+class OFPMatch(StringifyMixin):
+ def __init__(self, fields=[], type_=None, length=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 not length is None:
+ self.length = length
+ 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))
@@ -1950,7 +2023,7 @@ class OFPMatch(object):
self._flow.mpls_tc = mpls_tc
-class OFPMatchField(object):
+class OFPMatchField(StringifyMixin):
_FIELDS_HEADERS = {}
@staticmethod
@@ -1963,13 +2036,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_2.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)
@@ -1988,9 +2064,8 @@ class OFPMatchField(object):
@classmethod
def field_parser(cls, header, buf, offset):
- hasmask = (header >> 8) & 1
mask = None
- if hasmask:
+ if ofproto_v1_2.oxm_tlv_header_extract_hasmask(header):
pack_str = '!' + cls.pack_str[1:] * 2
(value, mask) = struct.unpack_from(pack_str, buf, offset + 4)
else:
@@ -1998,8 +2073,7 @@ class OFPMatchField(object):
return cls(header, value, mask)
def serialize(self, buf, offset):
- hasmask = (self.header >> 8) & 1
- if hasmask:
+ if ofproto_v1_2.oxm_tlv_header_extract_hasmask(self.header):
self.put_w(buf, offset, self.value, self.mask)
else:
self.put(buf, offset, self.value)
@@ -2035,6 +2109,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_2.OXM_OF_IN_PORT])
class MTInPort(OFPMatchField):
@@ -2303,8 +2394,7 @@ class MTArpTha(OFPMatchField):
class MTIPv6(object):
@classmethod
def field_parser(cls, header, buf, offset):
- hasmask = (header >> 8) & 1
- if hasmask:
+ if ofproto_v1_2.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:]))
--
1.8.1.5
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:
Build for Windows Store.
http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel