Currently, Ryu does not have the parser for Controller-to-Switch
one-way messages, but when testing Actions or Match fields,
OFPFlowMod parser is convenient in order to test them.

This patch implements the parser for OFPFlowMod messages.

Signed-off-by: IWASE Yusuke <iwase.yusu...@gmail.com>
---
 ryu/ofproto/ofproto_v1_0_parser.py    | 34 +++++++++++++++++++++++++++++-----
 ryu/ofproto/ofproto_v1_2_parser.py    | 26 ++++++++++++++++++++++++++
 ryu/ofproto/ofproto_v1_3_parser.py    | 26 ++++++++++++++++++++++++++
 ryu/ofproto/ofproto_v1_4_parser.py    | 26 ++++++++++++++++++++++++++
 ryu/ofproto/ofproto_v1_5_parser.py    | 26 ++++++++++++++++++++++++++
 ryu/tests/unit/ofproto/test_parser.py | 10 +++++-----
 6 files changed, 138 insertions(+), 10 deletions(-)

diff --git a/ryu/ofproto/ofproto_v1_0_parser.py 
b/ryu/ofproto/ofproto_v1_0_parser.py
index d330612..0ccc64e 100644
--- a/ryu/ofproto/ofproto_v1_0_parser.py
+++ b/ryu/ofproto/ofproto_v1_0_parser.py
@@ -3073,6 +3073,7 @@ class OFPPacketOut(MsgBase):
                       self.buffer_id, self.in_port, self._actions_len)
 
 
+@_register_parser
 @_set_msg_type(ofproto.OFPT_FLOW_MOD)
 class OFPFlowMod(MsgBase):
     """
@@ -3129,15 +3130,14 @@ class OFPFlowMod(MsgBase):
                 priority, buffer_id, out_port, flags, actions)
             datapath.send_msg(req)
     """
-    def __init__(self, datapath, match, cookie, command,
+    def __init__(self, datapath, match=None, cookie=0,
+                 command=ofproto.OFPFC_ADD,
                  idle_timeout=0, hard_timeout=0,
                  priority=ofproto.OFP_DEFAULT_PRIORITY,
                  buffer_id=0xffffffff, out_port=ofproto.OFPP_NONE,
                  flags=0, actions=None):
-        if actions is None:
-            actions = []
         super(OFPFlowMod, self).__init__(datapath)
-        self.match = match
+        self.match = OFPMatch() if match is None else match
         self.cookie = cookie
         self.command = command
         self.idle_timeout = idle_timeout
@@ -3146,7 +3146,7 @@ class OFPFlowMod(MsgBase):
         self.buffer_id = buffer_id
         self.out_port = out_port
         self.flags = flags
-        self.actions = actions
+        self.actions = [] if actions is None else actions
 
     def _serialize_body(self):
         offset = ofproto.OFP_HEADER_SIZE
@@ -3165,6 +3165,30 @@ class OFPFlowMod(MsgBase):
                 a.serialize(self.buf, offset)
                 offset += a.len
 
+    @classmethod
+    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
+        msg = super(OFPFlowMod, cls).parser(
+            datapath, version, msg_type, msg_len, xid, buf)
+        offset = ofproto.OFP_HEADER_SIZE
+
+        msg.match = OFPMatch.parse(msg.buf, offset)
+        offset += ofproto.OFP_MATCH_SIZE
+
+        (msg.cookie, msg.command, msg.idle_timeout, msg.hard_timeout,
+         msg.priority, msg.buffer_id, msg.out_port,
+         msg.flags) = struct.unpack_from(
+            ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf, offset)
+        offset = ofproto.OFP_FLOW_MOD_SIZE
+
+        actions = []
+        while offset < msg_len:
+            a = OFPAction.parser(buf, offset)
+            actions.append(a)
+            offset += a.len
+        msg.actions = actions
+
+        return msg
+
 
 @_set_msg_type(ofproto.OFPT_PORT_MOD)
 class OFPPortMod(MsgBase):
diff --git a/ryu/ofproto/ofproto_v1_2_parser.py 
b/ryu/ofproto/ofproto_v1_2_parser.py
index 6c418b4..b755499 100644
--- a/ryu/ofproto/ofproto_v1_2_parser.py
+++ b/ryu/ofproto/ofproto_v1_2_parser.py
@@ -862,6 +862,7 @@ class OFPPacketOut(MsgBase):
                       self.buffer_id, self.in_port, self.actions_len)
 
 
+@_register_parser
 @_set_msg_type(ofproto.OFPT_FLOW_MOD)
 class OFPFlowMod(MsgBase):
     """
@@ -971,6 +972,31 @@ class OFPFlowMod(MsgBase):
             inst.serialize(self.buf, offset)
             offset += inst.len
 
+    @classmethod
+    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
+        msg = super(OFPFlowMod, cls).parser(
+            datapath, version, msg_type, msg_len, xid, buf)
+
+        (msg.cookie, msg.cookie_mask, msg.table_id,
+         msg.command, msg.idle_timeout, msg.hard_timeout,
+         msg.priority, msg.buffer_id, msg.out_port,
+         msg.out_group, msg.flags) = struct.unpack_from(
+            ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf,
+            ofproto.OFP_HEADER_SIZE)
+        offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE
+
+        msg.match = OFPMatch.parser(buf, offset)
+        offset += utils.round_up(msg.match.length, 8)
+
+        instructions = []
+        while offset < msg_len:
+            i = OFPInstruction.parser(buf, offset)
+            instructions.append(i)
+            offset += i.len
+        msg.instructions = instructions
+
+        return msg
+
 
 class OFPInstruction(StringifyMixin):
     _INSTRUCTION_TYPES = {}
diff --git a/ryu/ofproto/ofproto_v1_3_parser.py 
b/ryu/ofproto/ofproto_v1_3_parser.py
index 4d37cb2..776b396 100644
--- a/ryu/ofproto/ofproto_v1_3_parser.py
+++ b/ryu/ofproto/ofproto_v1_3_parser.py
@@ -2545,6 +2545,7 @@ class OFPPacketOut(MsgBase):
                       self.buffer_id, self.in_port, self.actions_len)
 
 
+@_register_parser
 @_set_msg_type(ofproto.OFPT_FLOW_MOD)
 class OFPFlowMod(MsgBase):
     """
@@ -2657,6 +2658,31 @@ class OFPFlowMod(MsgBase):
             inst.serialize(self.buf, offset)
             offset += inst.len
 
+    @classmethod
+    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
+        msg = super(OFPFlowMod, cls).parser(
+            datapath, version, msg_type, msg_len, xid, buf)
+
+        (msg.cookie, msg.cookie_mask, msg.table_id,
+         msg.command, msg.idle_timeout, msg.hard_timeout,
+         msg.priority, msg.buffer_id, msg.out_port,
+         msg.out_group, msg.flags) = struct.unpack_from(
+            ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf,
+            ofproto.OFP_HEADER_SIZE)
+        offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE
+
+        msg.match = OFPMatch.parser(buf, offset)
+        offset += utils.round_up(msg.match.length, 8)
+
+        instructions = []
+        while offset < msg_len:
+            i = OFPInstruction.parser(buf, offset)
+            instructions.append(i)
+            offset += i.len
+        msg.instructions = instructions
+
+        return msg
+
 
 class OFPInstruction(StringifyMixin):
     _INSTRUCTION_TYPES = {}
diff --git a/ryu/ofproto/ofproto_v1_4_parser.py 
b/ryu/ofproto/ofproto_v1_4_parser.py
index 9478fba..1e0873f 100644
--- a/ryu/ofproto/ofproto_v1_4_parser.py
+++ b/ryu/ofproto/ofproto_v1_4_parser.py
@@ -4213,6 +4213,7 @@ class OFPPacketOut(MsgBase):
                       self.buffer_id, self.in_port, self.actions_len)
 
 
+@_register_parser
 @_set_msg_type(ofproto.OFPT_FLOW_MOD)
 class OFPFlowMod(MsgBase):
     """
@@ -4329,6 +4330,31 @@ class OFPFlowMod(MsgBase):
             inst.serialize(self.buf, offset)
             offset += inst.len
 
+    @classmethod
+    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
+        msg = super(OFPFlowMod, cls).parser(
+            datapath, version, msg_type, msg_len, xid, buf)
+
+        (msg.cookie, msg.cookie_mask, msg.table_id,
+         msg.command, msg.idle_timeout, msg.hard_timeout,
+         msg.priority, msg.buffer_id, msg.out_port,
+         msg.out_group, msg.flags, msg.importance) = struct.unpack_from(
+            ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf,
+            ofproto.OFP_HEADER_SIZE)
+        offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE
+
+        msg.match = OFPMatch.parser(buf, offset)
+        offset += utils.round_up(msg.match.length, 8)
+
+        instructions = []
+        while offset < msg_len:
+            i = OFPInstruction.parser(buf, offset)
+            instructions.append(i)
+            offset += i.len
+        msg.instructions = instructions
+
+        return msg
+
 
 class OFPInstruction(StringifyMixin):
     _INSTRUCTION_TYPES = {}
diff --git a/ryu/ofproto/ofproto_v1_5_parser.py 
b/ryu/ofproto/ofproto_v1_5_parser.py
index 23a8e4e..81571e0 100644
--- a/ryu/ofproto/ofproto_v1_5_parser.py
+++ b/ryu/ofproto/ofproto_v1_5_parser.py
@@ -5066,6 +5066,7 @@ class OFPPacketOut(MsgBase):
                       self.buffer_id, self.actions_len)
 
 
+@_register_parser
 @_set_msg_type(ofproto.OFPT_FLOW_MOD)
 class OFPFlowMod(MsgBase):
     """
@@ -5182,6 +5183,31 @@ class OFPFlowMod(MsgBase):
             inst.serialize(self.buf, offset)
             offset += inst.len
 
+    @classmethod
+    def parser(cls, datapath, version, msg_type, msg_len, xid, buf):
+        msg = super(OFPFlowMod, cls).parser(
+            datapath, version, msg_type, msg_len, xid, buf)
+
+        (msg.cookie, msg.cookie_mask, msg.table_id,
+         msg.command, msg.idle_timeout, msg.hard_timeout,
+         msg.priority, msg.buffer_id, msg.out_port,
+         msg.out_group, msg.flags, msg.importance) = struct.unpack_from(
+            ofproto.OFP_FLOW_MOD_PACK_STR0, msg.buf,
+            ofproto.OFP_HEADER_SIZE)
+        offset = ofproto.OFP_FLOW_MOD_SIZE - ofproto.OFP_HEADER_SIZE
+
+        msg.match = OFPMatch.parser(buf, offset)
+        offset += utils.round_up(msg.match.length, 8)
+
+        instructions = []
+        while offset < msg_len:
+            i = OFPInstruction.parser(buf, offset)
+            instructions.append(i)
+            offset += i.len
+        msg.instructions = instructions
+
+        return msg
+
 
 class OFPInstruction(StringifyMixin):
     _INSTRUCTION_TYPES = {}
diff --git a/ryu/tests/unit/ofproto/test_parser.py 
b/ryu/tests/unit/ofproto/test_parser.py
index dc2940e..dcbee23 100644
--- a/ryu/tests/unit/ofproto/test_parser.py
+++ b/ryu/tests/unit/ofproto/test_parser.py
@@ -39,7 +39,7 @@ implemented = {
         ofproto_v1_0.OFPT_FEATURES_REQUEST: (False, True),
         ofproto_v1_0.OFPT_FEATURES_REPLY: (True, False),
         ofproto_v1_0.OFPT_PACKET_IN: (True, False),
-        ofproto_v1_0.OFPT_FLOW_MOD: (False, True),
+        ofproto_v1_0.OFPT_FLOW_MOD: (True, True),
     },
     3: {
         ofproto_v1_2.OFPT_FEATURES_REQUEST: (False, True),
@@ -51,7 +51,7 @@ implemented = {
         ofproto_v1_2.OFPT_FLOW_REMOVED: (True, False),
         ofproto_v1_2.OFPT_PORT_STATUS: (True, False),
         ofproto_v1_2.OFPT_PACKET_OUT: (False, True),
-        ofproto_v1_2.OFPT_FLOW_MOD: (False, True),
+        ofproto_v1_2.OFPT_FLOW_MOD: (True, True),
         ofproto_v1_2.OFPT_GROUP_MOD: (False, True),
         ofproto_v1_2.OFPT_PORT_MOD: (False, True),
         ofproto_v1_2.OFPT_TABLE_MOD: (False, True),
@@ -74,7 +74,7 @@ implemented = {
         ofproto_v1_3.OFPT_FLOW_REMOVED: (True, False),
         ofproto_v1_3.OFPT_PORT_STATUS: (True, False),
         ofproto_v1_3.OFPT_PACKET_OUT: (False, True),
-        ofproto_v1_3.OFPT_FLOW_MOD: (False, True),
+        ofproto_v1_3.OFPT_FLOW_MOD: (True, True),
         ofproto_v1_3.OFPT_GROUP_MOD: (False, True),
         ofproto_v1_3.OFPT_PORT_MOD: (False, True),
         ofproto_v1_3.OFPT_METER_MOD: (False, True),
@@ -101,7 +101,7 @@ implemented = {
         ofproto_v1_4.OFPT_FLOW_REMOVED: (True, False),
         ofproto_v1_4.OFPT_PORT_STATUS: (True, False),
         ofproto_v1_4.OFPT_PACKET_OUT: (False, True),
-        ofproto_v1_4.OFPT_FLOW_MOD: (False, True),
+        ofproto_v1_4.OFPT_FLOW_MOD: (True, True),
         ofproto_v1_4.OFPT_GROUP_MOD: (True, True),
         ofproto_v1_4.OFPT_PORT_MOD: (False, True),
         ofproto_v1_4.OFPT_METER_MOD: (True, True),
@@ -131,7 +131,7 @@ implemented = {
         ofproto_v1_5.OFPT_FLOW_REMOVED: (True, False),
         ofproto_v1_5.OFPT_PORT_STATUS: (True, False),
         ofproto_v1_5.OFPT_PACKET_OUT: (False, True),
-        ofproto_v1_5.OFPT_FLOW_MOD: (False, True),
+        ofproto_v1_5.OFPT_FLOW_MOD: (True, True),
         ofproto_v1_5.OFPT_GROUP_MOD: (True, True),
         ofproto_v1_5.OFPT_PORT_MOD: (False, True),
         ofproto_v1_5.OFPT_METER_MOD: (True, True),
-- 
2.7.4


------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity 
planning reports. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e
_______________________________________________
Ryu-devel mailing list
Ryu-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to