Signed-off-by: FUJITA Tomonori <fujita.tomon...@lab.ntt.co.jp>
---
 ryu/ofproto/ofproto_v1_2.py        |    2 +-
 ryu/ofproto/ofproto_v1_2_parser.py |   78 ++++++++++++++++++++++++++++++++---
 2 files changed, 72 insertions(+), 8 deletions(-)

diff --git a/ryu/ofproto/ofproto_v1_2.py b/ryu/ofproto/ofproto_v1_2.py
index b85574b..f15db82 100644
--- a/ryu/ofproto/ofproto_v1_2.py
+++ b/ryu/ofproto/ofproto_v1_2.py
@@ -213,7 +213,7 @@ assert (calcsize(OFP_OXM_EXPERIMENTER_HEADER_PACK_STR) ==
         OFP_OXM_EXPERIMENTER_HEADER_SIZE)
 
 # enum ofp_instruction_type
-OFPID_GOTO_TABLE = 1  # Setup the next table in the lookup pipeline.
+OFPIT_GOTO_TABLE = 1  # Setup the next table in the lookup pipeline.
 OFPIT_WRITE_METADATA = 2  # Setup the metadata field for use later in
                           # pipeline.
 OFPIT_WRITE_ACTIONS = 3  # Write the action(s) onto the datapath
diff --git a/ryu/ofproto/ofproto_v1_2_parser.py 
b/ryu/ofproto/ofproto_v1_2_parser.py
index acbf5c7..0bee831 100644
--- a/ryu/ofproto/ofproto_v1_2_parser.py
+++ b/ryu/ofproto/ofproto_v1_2_parser.py
@@ -366,18 +366,45 @@ class OFPFlowMod(MsgBase):
             offset += inst.len
 
 
+class OFPInstruction(object):
+    _INSTRUCTION_TYPES = {}
+
+    @staticmethod
+    def register_instruction_type(types):
+        def _register_instruction_type(cls):
+            for type_ in types:
+                OFPInstruction._INSTRUCTION_TYPES[type_] = cls
+            return cls
+        return _register_instruction_type
+
+    @classmethod
+    def parser(cls, buf, offset):
+        (type_, len_) = struct.unpack_from('!HH', buf, offset)
+        cls_ = cls._INSTRUCTION_TYPES.get(type_)
+        return cls_.parser(buf, offset)
+
+
+@OFPInstruction.register_instruction_type([ofproto_v1_2.OFPIT_GOTO_TABLE])
 class OFPInstructionGotoTable(object):
     def __init__(self, table_id):
         super(OFPInstructionGotoTable, self).__init__()
-        self.type = ofproto_v1_2.OFPID_GOTO_TABLE
+        self.type = ofproto_v1_2.OFPIT_GOTO_TABLE
         self.len = ofproto_v1_2.OFP_INSTRUCTION_GOTO_TABLE_SIZE
         self.table_id = table_id
 
+    @classmethod
+    def parser(cls, buf, offset):
+        (type_, len_, table_id) = struct.unpack_from(
+            ofproto_v1_2.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR,
+            buf, offset)
+        return cls(table_id)
+
     def serialize(self, buf, offset):
         msg_pack_into(ofproto_v1_2.OFP_INSTRUCTION_GOTO_TABLE_PACK_STR,
                       buf, offset, self.type, self.len, self.table_id)
 
 
+@OFPInstruction.register_instruction_type([ofproto_v1_2.OFPIT_WRITE_METADATA])
 class OFPInstructionWriteMetadata(object):
     def __init__(self, metadata, metadata_mask):
         super(OFPInstructionWriteMetadata, self).__init__()
@@ -386,23 +413,51 @@ class OFPInstructionWriteMetadata(object):
         self.metadata = metadata
         self.metadata_mask = metadata_mask
 
+    @classmethod
+    def parser(cls, buf, offset):
+        (type_, len_, metadata, metadata_mask) = struct.unpack_from(
+            ofproto_v1_2.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR,
+            buf, offset)
+        return cls(metadata, metadata_mask)
+
     def serialize(self, buf, offset):
         msg_pack_into(ofproto_v1_2.OFP_INSTRUCTION_WRITE_METADATA_PACK_STR,
                       buf, offset, self.type, self.len, self.metadata,
                       self.metadata_mask)
 
 
+@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):
-    def __init__(self, type_, actions):
+    def __init__(self, type_, len_, actions=None):
         super(OFPInstructionActions, self).__init__()
         self.type = type_
+        self.len = len_
         self.actions = actions
 
+    @classmethod
+    def parser(cls, buf, offset):
+        (type_, len_) = struct.unpack_from(
+            ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_PACK_STR,
+            buf, offset)
+
+        offset += ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_SIZE
+        actions = []
+        actions_len = len_ - ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_SIZE
+        while actions_len > 0:
+            a = OFPAction.parser(buf, offset)
+            actions.append(a)
+            actions_len -= a.len
+
+        return cls(type_, len_, actions)
+
     def serialize(self, buf, offset):
         action_offset = offset + ofproto_v1_2.OFP_INSTRUCTION_ACTIONS_SIZE
-        for a in self.actions:
-            a.serialize(buf, action_offset)
-            action_offset += a.len
+        if self.actions:
+            for a in self.actions:
+                a.serialize(buf, action_offset)
+                action_offset += a.len
 
         self.len = action_offset - offset
 
@@ -824,7 +879,7 @@ class OFPStatsReply(MsgBase):
         if stats_type_cls.cls_body_single_struct:
             msg.body = body[0]
         else:
-            msg.bdoy = body
+            msg.body = body
 
         return msg
 
@@ -879,7 +934,7 @@ class OFPFlowStatsRequest(OFPStatsRequest):
 class OFPFlowStats(object):
     def __init__(self, length, table_id, duration_sec, duration_nsec,
                  priority, idle_timeout, hard_timeout, cookie, packet_count,
-                 byte_count, match):
+                 byte_count, match, instructions=None):
         super(OFPFlowStats, self).__init__()
         self.length = length
         self.table_id = table_id
@@ -892,6 +947,7 @@ class OFPFlowStats(object):
         self.packet_count = packet_count
         self.byte_count = byte_count
         self.match = match
+        self.instructions = instructions
 
     @classmethod
     def parser(cls, buf, offset):
@@ -905,6 +961,14 @@ class OFPFlowStats(object):
                    ofproto_v1_2.OFP_MATCH_SIZE)
         match = OFPMatch.parser(buf, offset)
 
+        match_length = utils.round_up(match.length, 8)
+        inst_length = (length - (ofproto_v1_2.OFP_FLOW_STATS_SIZE -
+                                 ofproto_v1_2.OFP_MATCH_SIZE + match_length))
+        offset += match_length
+        while inst_length > 0:
+            inst = OFPInstruction.parser(buf, offset)
+            inst_length -= inst.len
+
         return cls(length, table_id, duration_sec, duration_nsec, priority,
                    idle_timeout, hard_timeout, cookie, packet_count,
                    byte_count, match)
-- 
1.7.4.4


------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to