[ovs-dev] [PATCH 2/2] ofp-util: Treat a packet-out in_port of OFPP_CONTROLLER as OFPP_NONE.

Ben Pfaff blp at nicira.com
Fri Apr 27 20:35:01 UTC 2012


Some OpenFlow 1.0 controllers incorrectly use OPFP_CONTROLLER as the
in_port in packet-out messages, when OFPP_NONE is their intent.  Until now,
Open vSwitch has rejected such requests with an error message.  This commit
makes Open vSwitch instead treat OFPP_CONTROLLER the same as OFPP_NONE for
compatibility with those controllers.

Suggested-by: Rob Sherwood <rob.sherwood at bigswitch.com>
Signed-off-by: Ben Pfaff <blp at nicira.com>
---
 lib/ofp-util.c   |    9 +++++++--
 tests/ofproto.at |   33 +++++++++++++++++++++++++++++++++
 2 files changed, 40 insertions(+), 2 deletions(-)

diff --git a/lib/ofp-util.c b/lib/ofp-util.c
index ae9b30d..9843e63 100644
--- a/lib/ofp-util.c
+++ b/lib/ofp-util.c
@@ -2223,8 +2223,13 @@ ofputil_decode_packet_out(struct ofputil_packet_out *po,
 
     po->buffer_id = ntohl(opo->buffer_id);
     po->in_port = ntohs(opo->in_port);
-    if (po->in_port >= OFPP_MAX && po->in_port != OFPP_LOCAL
-        && po->in_port != OFPP_NONE) {
+    if (po->in_port == OFPP_CONTROLLER) {
+        /* The OpenFlow 1.0 spec says OFPP_NONE is the correct in_port for a
+         * packet generated by the controller, but a lot of controllers
+         * mistakenly use OFPP_CONTROLLER instead.  Fix it up for them. */
+        po->in_port = OFPP_NONE;
+    } else if (po->in_port >= OFPP_MAX && po->in_port != OFPP_LOCAL
+               && po->in_port != OFPP_NONE) {
         VLOG_WARN_RL(&bad_ofmsg_rl, "packet-out has bad input port %#"PRIx16,
                      po->in_port);
         return OFPERR_NXBRC_BAD_IN_PORT;
diff --git a/tests/ofproto.at b/tests/ofproto.at
index dbddea8..af89c9d 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -529,3 +529,36 @@ check_async 7 OFPR_ACTION OFPPR_ADD
 ovs-appctl -t ovs-ofctl exit
 OVS_VSWITCHD_STOP
 AT_CLEANUP
+
+dnl This test checks that OFPT_PACKET_OUT accepts both OFPP_NONE (as
+dnl specified by OpenFlow 1.0) and OFPP_CONTROLLER (used by some
+dnl controllers despite the spec) as meaning a packet that was generated
+dnl by the controller.
+AT_SETUP([ofproto - packet-out from controller])
+OVS_VSWITCHD_START
+
+# Start a monitor listening for packet-ins.
+AT_CHECK([ovs-ofctl -P openflow10 monitor br0 --detach --no-chdir --pidfile])
+ovs-appctl -t ovs-ofctl ofctl/send 0109000c0123456700000080
+ovs-appctl -t ovs-ofctl ofctl/barrier
+ovs-appctl -t ovs-ofctl ofctl/set-output-file monitor.log
+AT_CAPTURE_FILE([monitor.log])
+
+# Send some packet-outs with OFPP_NONE and OFPP_CONTROLLER (65533) as in_port.
+AT_CHECK([ovs-ofctl packet-out br0 none controller '0001020304050010203040501234'])
+AT_CHECK([ovs-ofctl packet-out br0 65533 controller '0001020304050010203040505678'])
+
+# Stop the monitor and check its output.
+ovs-appctl -t ovs-ofctl ofctl/barrier
+ovs-appctl -t ovs-ofctl exit
+
+AT_CHECK([sed 's/ (xid=0x[[0-9a-fA-F]]*)//' monitor.log], [0], [dnl
+OFPT_PACKET_IN: total_len=14 in_port=NONE (via action) data_len=14 (unbuffered)
+priority:0,tunnel:0,in_port:0000,tci(0) mac(00:10:20:30:40:50->00:01:02:03:04:05) type:1234 proto:0 tos:0 ttl:0 ip(0.0.0.0->0.0.0.0)
+OFPT_PACKET_IN: total_len=14 in_port=NONE (via action) data_len=14 (unbuffered)
+priority:0,tunnel:0,in_port:0000,tci(0) mac(00:10:20:30:40:50->00:01:02:03:04:05) type:5678 proto:0 tos:0 ttl:0 ip(0.0.0.0->0.0.0.0)
+OFPT_BARRIER_REPLY:
+])
+
+OVS_VSWITCHD_STOP
+AT_CLEANUP
-- 
1.7.2.5




More information about the dev mailing list