vconn: Ignore async messages before version negotiation completes.
authorBen Pfaff <blp@nicira.com>
Thu, 15 Jan 2009 22:31:55 +0000 (14:31 -0800)
committerBen Pfaff <blp@nicira.com>
Thu, 15 Jan 2009 22:31:55 +0000 (14:31 -0800)
The kernel can send a packet_in or other asynchronous message to
the secchan before the version negotiation step is finished, which
causes the secchan to drop the connection and try again.  This commit
fixes the problem.

Fixes bug #368.

lib/vconn.c

index 12d3ad4f2ff67b688b9ef9ee602cb76fe85b95bd..f22d7feb6c97789531e597d75a2098a162425551 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (c) 2008 The Board of Trustees of The Leland Stanford
+/* Copyright (c) 2008, 2009 The Board of Trustees of The Leland Stanford
  * Junior University
  * 
  * We are making the OpenFlow specification and associated documentation
@@ -464,6 +464,7 @@ do_recv(struct vconn *vconn, struct ofpbuf **msgp)
 {
     int retval;
 
+again:
     retval = (vconn->class->recv)(vconn, msgp);
     if (!retval) {
         struct ofp_header *oh;
@@ -483,6 +484,20 @@ do_recv(struct vconn *vconn, struct ofpbuf **msgp)
             && oh->type != OFPT_VENDOR)
         {
             if (vconn->version < 0) {
+                if (oh->type == OFPT_PACKET_IN
+                    || oh->type == OFPT_FLOW_EXPIRED
+                    || oh->type == OFPT_PORT_STATUS) {
+                    /* The kernel datapath is stateless and doesn't really
+                     * support version negotiation, so it can end up sending
+                     * these asynchronous message before version negotiation
+                     * is complete.  Just ignore them.
+                     *
+                     * (After we move OFPT_PORT_STATUS messages from the kernel
+                     * into secchan, we won't get those here, since secchan
+                     * does proper version negotiation.) */
+                    ofpbuf_delete(*msgp);
+                    goto again;
+                }
                 VLOG_ERR_RL(&rl, "%s: received OpenFlow message type %"PRIu8" "
                             "before version negotiation complete",
                             vconn->name, oh->type);