If the buffer_id of a message received by a controller is -1 (0xffffffff)
then no buffer is used by that message.  In this case the controller may
allocate a buffer for use by resulting packet_in messages unless the
max_len of output action that causes the packet_in message is
OFPCML_NO_BUFFER (0xffff).

If a buffer is allocated by the controller then the buffer_id of packet_in
messages will have a value other than -1.

Conversely if no buffer is used in a packet_in message that results from a
message received by a controller, because none was specified in the message
received (its buffer_id was -1) and either max_len of the output action is
OFPCML_NO_BUFFER or the controller does not to allocate a buffer for any
other reason then the value of the buffer_id in packet_in messages will be
-1.

Thus, in the case that buffer_id is -1 in a packet_out message setting
max_len of output actions to OFPCML_NO_BUFFER will ensure the packet_in
messages with buffer_id -1. That is the buffer_id of the packet_out and
packet_in messages will match.

Another approach would be to not verify the buffer_id if it is -1. But it
seems more thorough to exercise the OFPCML_NO_BUFFER behaviour of the
controller.

I noticed this when using Open vSwitch's "make ryu-check" as
Open vSwitch allocates buffers if OFPCML_NO_BUFFER is not in effect.
This appears to be compliant with section A.2.5 the OpenFlow 1.2 spec.

Signed-off-by: Simon Horman <[email protected]>
---
v2
* Correct spelling errors

 ryu/tests/integrated/test_request_reply_v12.py | 35 ++++++++++++++++++++++++--
 1 file changed, 33 insertions(+), 2 deletions(-)

diff --git a/ryu/tests/integrated/test_request_reply_v12.py 
b/ryu/tests/integrated/test_request_reply_v12.py
index b60a2ba..eb76028 100644
--- a/ryu/tests/integrated/test_request_reply_v12.py
+++ b/ryu/tests/integrated/test_request_reply_v12.py
@@ -916,6 +916,35 @@ class RunTest(tester.TestFlowBase):
     def verify_flow_removed_table_id(self, dp, msg):
         return self._verify_flow_removed(dp, msg)
 
+    def _max_len(self, dp, len_, buffer_id=0xffffffff):
+        if buffer_id == 0xffffffff:
+            # If the buffer_id of a message received by a controller is
+            # -1 (0xffffffff) then no buffer is used by that message.
+            # In this case the controller may allocate a buffer for use by
+            # resulting packet_in messages unless the max_len of output
+            # action that causes the packet_in message is OFPCML_NO_BUFFER
+            # (0xffff).
+            #
+            # If a buffer is allocated by the controller then the buffer_id
+            # of packet_in messages will have a value other than -1.
+            #
+            # Conversely if no buffer is used in a packet_in message that
+            # results from a message received by a controller, because none
+            # was specified in the message received (its buffer_id was -1)
+            # and either max_len of the output action is OFPCML_NO_BUFFER
+            # or the controller does not to allocate a buffer for any other
+            # reason then the value of the buffer_id in packet_in messages
+            # will be -1.
+            #
+            # Thus, in the case that buffer_id is -1 in a packet_out
+            # message setting max_len of output actions to OFPCML_NO_BUFFER
+            # will ensure the packet_in messages with buffer_id -1. That
+            # is the buffer_id of the packet_out and packet_in messages
+            # will match.
+            return dp.ofproto.OFPCML_NO_BUFFER
+        else:
+            return len_
+
     def _send_packet_out(self, dp, buffer_id=0xffffffff,
                          in_port=None, output=None, data=''):
         if in_port is None:
@@ -928,7 +957,8 @@ class RunTest(tester.TestFlowBase):
         self._verify['in_port'] = in_port
         self._verify['data'] = data
 
-        actions = [dp.ofproto_parser.OFPActionOutput(output, len(data))]
+        max_len = self._max_len(dp, len(data), buffer_id)
+        actions = [dp.ofproto_parser.OFPActionOutput(output, max_len)]
         m = dp.ofproto_parser.OFPPacketOut(dp, buffer_id, in_port,
                                            actions, data)
         dp.send_msg(m)
@@ -983,7 +1013,8 @@ class RunTest(tester.TestFlowBase):
         match = dp.ofproto_parser.OFPMatch()
         match.set_in_port(in_port)
         out = dp.ofproto.OFPP_CONTROLLER
-        actions = [dp.ofproto_parser.OFPActionOutput(out, 0)]
+        max_len = self._max_len(dp, 0)
+        actions = [dp.ofproto_parser.OFPActionOutput(out, max_len)]
         self.mod_flow(dp, actions=actions, match=match, table_id=table_id)
         dp.send_barrier()
 
-- 
1.8.5.2


------------------------------------------------------------------------------
Start Your Social Network Today - Download eXo Platform
Build your Enterprise Intranet with eXo Platform Software
Java Based Open Source Intranet - Social, Extensible, Cloud Ready
Get Started Now And Turn Your Intranet Into A Collaboration Platform
http://p.sf.net/sfu/ExoPlatform
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to