On Wed, Jun 12, 2013 at 07:44:11PM +0900, YAMAMOTO Takashi wrote:
> 
> 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
> +
> +

good clean up.


>  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(

OFP_SWITCH_FEATURES_PACK_STR should be fixed to drop reserved?
i.e. '4x' instead of 'I'

>               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
> 

-- 
yamahata

------------------------------------------------------------------------------
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

Reply via email to