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 <[email protected]> Signed-off-by: Ben Pfaff <[email protected]> --- 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 _______________________________________________ dev mailing list [email protected] http://openvswitch.org/mailman/listinfo/dev
